Подтвердить что ты не робот

Определить конфигурацию решения (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");

Также безрезультатно. Любые идеи?

4b9b3361

Ответ 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 не предназначен для предоставления параметра).