Определить конфигурацию решения (debug/release) при запуске шаблона T4
У меня есть шаблон T4, который может выводить либо оптимизированный контент, либо стандартный контент на основе флага. В настоящее время я вручную меняю флаг на основе моих потребностей.
Мне бы очень хотелось установить флажок на основе конфигурации решения в Visual Studio. Если установить для построения в режиме отладки, я бы выводил стандартный контент. Если установить в режиме Release, я бы оптимизировал контент. Я нашел еще один вопрос T4, который выглядит многообещающим: T4 Text Template - можно ли получить символы компиляции с хоста?
Однако в моем случае я хотел бы сделать что-то вроде следующего:
<#@ template language="C#" hostspecific="True"
compilerOptions="/d:$(ConfigurationName)" #>
Так как я могу использовать $(SolutionDir) в директиве сборки:
<#@ assembly name="$(SolutionDir)\myreference.dll" #>
Я бы подумал, что /d: $(ConfigurationName) получит меня туда, куда мне нужно было идти, а затем я мог бы сделать следующее, чтобы установить мой флаг:
<#
#if Debug
optimize = false;
#else
optimize = true;
#endif
#>
Увы, это не работает. Я также попытался использовать:
Host.ResolveParameterValue("-", "-", "ConfigurationName");
Также безрезультатно. Любые идеи?
Ответы
Ответ 1
Как только я спрошу, но я нахожу фрагмент внизу эту статью MSDN, которая получает меня там, где мне нужно. Ответ здесь заключается в использовании интерфейса IServiceProvider для получения Visual Studio DTE. Вот код, который это делается (заранее извинился за жестко закодированный "Отладка" ):
var serviceProvider = Host as IServiceProvider;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
var configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name ;
optimize = (configName != "Debug");
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;
}
}
Ответ 2
Для людей, пытающихся получить эту работу во время разработки (сохранение файла), а также во время сборки (F5/F6), необходимы два метода.
Эмиль описывает метод времени разработки. Для времени сборки сначала необходимо указать параметр T4 в файле проекта:
<ItemGroup>
<T4ParameterValues Include="BuildConfiguration">
<Value>$(Configuration)</Value>
<Visible>false</Visible>
</T4ParameterValues>
</ItemGroup>
Затем вам нужно указать его в верхней части вашего .tt:
<#@ parameter type="System.String" name="BuildConfiguration" #>
И затем найдите, какой из них будет предоставлен:
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;
}
Необходимо включить логику для обоих, если вы хотите, чтобы ваш шаблон работал в обоих сценариях. Метод времени разработки не работает во время сборки (узел DTE не предназначен для предоставления решения), а метод времени сборки не работает во время разработки (MSBuild не предназначен для предоставления параметра).