运行T4模板时确定解决方案配置(调试/发布)

Emi*_*rch 24 t4

我有一个T4模板,可以根据标志输出优化内容或标准内容.目前我正在根据我的需要手动更改旗帜.

我喜欢做的是根据Visual Studio中的解决方案配置来设置标志.如果设置为在调试模式下构建,我将输出标准内容.如果设置为在发布模式下构建,我会改为优化内容.我发现另一个看起来很有希望的T4问题:T4文本模板 - 是否有可能从主机获取编译符号?

但是,在我的情况下,我想做类似以下的事情:

<#@ template language="C#" hostspecific="True" 
    compilerOptions="/d:$(ConfigurationName)" #>
Run Code Online (Sandbox Code Playgroud)

因为我可以在程序集指令中使用$(SolutionDir):

<#@ assembly name="$(SolutionDir)\myreference.dll" #>
Run Code Online (Sandbox Code Playgroud)

我认为/ d:$(ConfigurationName)会让我到达我需要去的地方,然后我可以执行以下操作来设置我的标志:

<#
#if Debug 
 optimize = false;
#else 
 optimize = true;
#endif 
#>
Run Code Online (Sandbox Code Playgroud)

唉,这似乎不起作用.我也尝试过使用:

Host.ResolveParameterValue("-", "-", "ConfigurationName");
Run Code Online (Sandbox Code Playgroud)

也无济于事.有任何想法吗?

Emi*_*rch 25

我刚刚问,但我在这篇MSDN文章的底部找到了一个片段,它让我得到了我需要的地方.这里的答案是使用IServiceProvider接口来获取Visual Studio DTE.这是完成它的代码(事先为硬编码的"Debug"道歉):

var serviceProvider = Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
var configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name ;
optimize = (configName != "Debug"); 
Run Code Online (Sandbox Code Playgroud)

UPDATE

此代码将检查活动项目的当前配置是否已打开优化.它仍然具有硬编码的属性名称,但更改的可能性更小.此外,使用项目的优化标志对我的场景很有意义(试图决定是否应该在我自己的代码中启用优化):

var serviceProvider = Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(EnvDTE.DTE)) as DTE;
config = dte.Solution
            .FindProjectItem(Host.TemplateFile)
            .ContainingProject
            .ConfigurationManager
            .ActiveConfiguration;
foreach(Property prop in config.Properties){
    if (prop.Name == "Optimize"){
        optimize = (bool)prop.Value;
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)


Cal*_*her 12

对于试图在设计时(文件保存)以及构建时(F5/F6)获得此工作的人,需要两种方法.

Emil描述了设计时方法.对于构建时,首先必须在项目文件中指定T4参数:

<ItemGroup>
  <T4ParameterValues Include="BuildConfiguration">
    <Value>$(Configuration)</Value>
    <Visible>false</Visible>    
  </T4ParameterValues>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

然后你必须在.tt的顶部引用它:

<#@ parameter type="System.String" name="BuildConfiguration" #>
Run Code Online (Sandbox Code Playgroud)

然后寻找恰好提供的那些:

string configurationName = Host.ResolveParameterValue("-", "-", "BuildConfiguration");
if (string.IsNullOrWhiteSpace(configurationName))
{
    var serviceProvider = (IServiceProvider)Host;
    var dte = (DTE)serviceProvider.GetService(typeof(DTE));
    configurationName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
}
Run Code Online (Sandbox Code Playgroud)

如果您希望模板在两种方案中都有效,则必须包含两者的逻辑.设计时方法在构建时不起作用(DTE主机不在于提供解决方案),并且构建时方法在设计时不起作用(MSBuild不在于提供参数).