T4 template VS2010 get host assembly

不问归期 提交于 2020-07-05 03:34:09

问题


I want to get a reference to assembly of a project in which T4 template is. I know I can get path to the project with, for example Host.ResolveAssemblyReference("$(ProjectDir)") and I could maybe add bin\\debug\\{projectName}.dll because my assembly names are named by project name, but that is not always the case and I'm creating reusable template, so I need path to dll or most preferably Assembly instance. I have also found how to get reference to the Project as explained here in method GetProjectContainingT4File, but then what?

Is there a way to get it?

BTW, I need that reference to access specific types and generate some code from them.


回答1:


Following simple code worked for me (VS 2013):

var path = this.Host.ResolveAssemblyReference("$(TargetPath)");
var asm = Assembly.LoadFrom(path);

Also you can find $(...) properties in project psot build steps editor.




回答2:


Ok, I managed to get the needed reference to assembly @FuleSnabel gave me a hint, although I did't use his suggestion.

Here's a part of my T4 template:

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".output" #>
<#@ Assembly Name="System.Core.dll" #>
<#@ Assembly Name="System.Windows.Forms.dll" #>
<#@ Assembly Name="System.Xml.Linq.dll" #>
<#@ Assembly Name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
<#@ Assembly Name="EnvDTE" #>
<#@ Assembly Name="EnvDTE80" #>
<#@ Assembly Name="VSLangProj" #>

<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Reflection" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE80" #>
<#@ include file="T4Toolbox.tt" #>
<#
    Project prj = GetProject();
    string fileName = "$(ProjectDir)bin\\debug\\" + prj.Properties.Item("OutputFileName").Value;
    string path = Host.ResolveAssemblyReference(fileName);
    Assembly asm = Assembly.LoadFrom(path);

    // ....
#> 

// generated code goes here

<#+
    Project GetProject()
    {
        var serviceProvider = Host as IServiceProvider;
        if (serviceProvider == null) 
        {
            throw new Exception("Visual Studio host not found!");
        }

        DTE dte = serviceProvider.GetService(typeof(SDTE)) as DTE;

        if (dte == null) 
        {
            throw new Exception("Visual Studio host not found!");
        }

        ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
        if (projectItem.Document == null) {
            projectItem.Open(Constants.vsViewKindCode);
        }

        return projectItem.ContainingProject;
    }
 #>

So, to find right path to assembly I had to get reference to the project in GetProject() method and then use project's property OutputFileName with prj.Properties.Item("OutputFileName").Value. Since I couldn't find anywhere what properties project has, I used enumeration and a loop to inspect Properties collection and then found what I need. Here's a loop code:

<#
// ....
foreach(Property prop in prj.Properties)
{
    #>
    <#= prop.Name #>
    <#
}
// ....
#>

I hope this will help someone.



来源:https://stackoverflow.com/questions/13970260/t4-template-vs2010-get-host-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!