如何在Template Codes 中能够加载所在的Project的Assembly,获取所有Type

1.首先要获取Project对象

2.分析得到Project对象生成的bin路径,也就是$(TargetPath)

3.Assembly.LoadFromFile( binpath )

4.asm.GetTypes(),这里要注意处理Reference Project


代码如下:

1.GetProject()

  Project GetProject()
    {
        var hostServiceProvider = (IServiceProvider)this.Host;
        var dte = (DTE)hostServiceProvider.GetService(typeof(DTE));      
        var item = dte.Solution.FindProjectItem(this.Host.TemplateFile);
        if (item != null && item.ContainingProject != null)
        {
             return item.ContainingProject;
        }
        return null;
    }

2.GetAssemblyPath,GetAssemblyDir(获取bin目录)

 string GetAssemblyPath(EnvDTE.Project vsProject)
        {
            string fullPath = vsProject.Properties.Item("FullPath").Value.ToString();
            string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
            string outputDir = Path.Combine(fullPath, outputPath);
            string outputFileName = vsProject.Properties.Item("OutputFileName").Value.ToString();      
            string assemblyPath = Path.Combine(outputDir, outputFileName);
            return assemblyPath;
        }
     string GetAssemblyDir(EnvDTE.Project vsProject)
        {
            string fullPath = vsProject.Properties.Item("FullPath").Value.ToString();
            string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
            string outputDir = Path.Combine(fullPath, outputPath);     
            return outputDir;
        }

3.获取asm中所有interface

 Type[] GetInterfaces()
      {
        var p = GetProject();
        string str = GetAssemblyPath(p);    
        var asm = Assembly.LoadFile(str);
        Type[] tps = new Type[]{};
        try
        {                   
            tps = asm.GetTypes();
        }
        catch (ReflectionTypeLoadException ex)
        {
            foreach (Exception loaderException in ex.LoaderExceptions)
            {
                WriteLine(loaderException.ToString());
            }   
        }         
        return tps.ToOtherTypeArrayEx(i=>i.IsInterface,i=>i);
      }


最后要注意Reference :

<#
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
#>
<#+
      System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
         {           
            var strDllDir = GetAssemblyDir(GetProject());
            var strs = args.Name.Split(',');
            var strNeedResolveDllPath = strDllDir + strs[0] + ".dll";
         
            if (System.IO.File.Exists(strNeedResolveDllPath))
                return Assembly.LoadFile(strNeedResolveDllPath);            
            return null;
         }
    #>


一些参考:

http://msdn.microsoft.com/en-us/library/envdte.dte.aspx

http://msdn.microsoft.com/en-us/library/vstudio/gg604090(v=vs.100).aspx

http://stackoverflow.com/questions/3548026/get-referenced-projects-path-in-t4-template

http://stackoverflow.com/questions/12952110/accessing-projects-via-dte-in-c-sharp-t4-template

http://stackoverflow.com/questions/5486593/getting-the-macro-value-of-projects-targetpath-via-dte

http://social.msdn.microsoft.com/Forums/vstudio/en-US/03d9d23f-e633-4a27-9b77-9029735cfa8d/how-to-get-the-right-output-path-from-envdteproject-by-code-if-show-advanced-build?forum=vsx



posted on   norsd  阅读(156)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示