Поделиться через


Вызов преобразования текста в процессе сборки

Преобразование текста можно вызвать как часть процесса сборки решения Visual Studio. Имеются задачи сборки, которые специализируются на преобразовании текста. Задачи сборки T4 запускают выполнение текстовых шаблонов времени разработки, а также компилируют текстовые шаблоны времени выполнения (предварительно обработанные).

Возможности задач построения несколько отличаются в зависимости от используемого обработчика сборки. При создании решения в Visual Studio текстовый шаблон может получить доступ к API Visual Studio (EnvDTE), если задан атрибут hostspecific="true". Но это не так, если вы создаете решение из командной строки или инициируете сборку сервера с помощью Visual Studio. В таких случаях сборка выполняется в MSBuild и используется другой узел T4. Это означает, что при создании текстового шаблона с помощью MSBuild невозможно получить доступ к таким же именам файлов проекта. Однако вы можете передать сведения о среде в текстовые шаблоны и обработчики директив с помощью параметров сборки.

Настройка компьютеров

Чтобы включить задачи сборки на компьютере разработки, установите пакет SDK моделирования для Visual Studio.

Примечание.

Компонент Text Template Transformation (Преобразование текстовых шаблонов) автоматически устанавливается как часть рабочей нагрузки разработки расширений Visual Studio. Его также можно установить на вкладке Отдельные компоненты Visual Studio Installer в категории Пакеты SDK, библиотеки и платформы. Установите компонент Пакет SDK для моделирования со вкладки Отдельные компоненты.

Если сервер сборки работает на компьютере, на котором не установлен Visual Studio, скопируйте следующие файлы на компьютер сборки с компьютера разработки:

  • %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VisualStudio\v16.0\TextTemplating

    • Microsoft.VisualStudio.TextTemplating.Sdk.Host.15.0.dll
    • Microsoft.TextTemplating.Build.Tasks.dll
    • Microsoft.TextTemplating.targets
  • %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0

    • Microsoft.VisualStudio.TextTemplating.15.0.dll
    • Microsoft.VisualStudio.TextTemplating.Interfaces.15.0.dll
    • Microsoft.VisualStudio.TextTemplating.VSHost.15.0.dll
  • %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\Common7\IDE\PublicAssemblies

    • Microsoft.VisualStudio.TextTemplating.Modeling.15.0.dll

Совет

Если вы получаете MissingMethodException метод Microsoft.CodeAnalysis при выполнении целевых объектов сборки TextTemplating на сервере сборки, убедитесь, что сборки Roslyn находятся в каталоге с именем Roslyn , который находится в том же каталоге, что и исполняемый файл сборки (например, msbuild.exe).

Изменение файла проекта

Измените файл проекта, чтобы настроить некоторые функции в MSBuild, например импорт целевых объектов преобразования текста.

В Обозреватель решений выберите "Выгрузить" в меню правой кнопкой мыши проекта. Это позволит изменить CSPROJ- или VBPROJ-файл в редакторе XML. После завершения редактирования нажмите кнопку "Перезагрузить".

Импорт целевых объектов преобразования текста

В Vbproj или CSPROJ-файле найдите последнюю Import Project строку.

После этой строки, если она существует, вставьте импорт шаблона текста:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v17.0\TextTemplating\Microsoft.TextTemplating.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v16.0\TextTemplating\Microsoft.TextTemplating.targets" />

Преобразование шаблонов в сборке

Предусмотрено несколько свойств, которые можно вставлять в файл проекта для управления задачей преобразования.

  • Выполнять задачу преобразования в начале каждой сборки:

    <PropertyGroup>
        <TransformOnBuild>true</TransformOnBuild>
    </PropertyGroup>
    
  • Например, перезаписывать файлы, доступные только для чтения, так как они не проверка выходить:

    <PropertyGroup>
        <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    </PropertyGroup>
    
  • Каждый раз преобразовывать все шаблоны:

    <PropertyGroup>
        <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
    </PropertyGroup>
    

    По умолчанию задача T4 MSBuild повторно создает выходной файл, если он старше:

    • файл шаблона
    • все файлы, включенные
    • все файлы, которые ранее были прочитаны шаблоном или обработчиком директив, который он использует

    Это более мощный тест зависимостей, чем используется командой Преобразования всех шаблонов в Visual Studio, которая сравнивает только даты шаблона и выходной файл.

Чтобы выполнить только преобразования текста в проекте, вызовите задачу TransformAll:

msbuild myProject.csproj /t:TransformAll

Чтобы преобразовать определенный текстовый шаблон:

msbuild myProject.csproj /t:Transform /p:TransformFile="Template1.tt"

В команде TransformFile можно использовать символы подстановки:

msbuild dsl.csproj /t:Transform /p:TransformFile="GeneratedCode\**\*.tt"

Управление исходным кодом

Не существует специальной встроенной интеграции с системой управления версиями. Однако можно добавить собственные расширения, например, чтобы проверка и проверка в созданном файле. По умолчанию задача преобразования текста избегает перезаписи файла, помеченного как доступный только для чтения. При обнаружении такого файла ошибка регистрируется в списке ошибок Visual Studio, и задача завершается ошибкой.

Чтобы указать, что доступные только для чтения файлы следует перезаписывать, вставьте такое свойство:

<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>

Если вы не настроите шаг после обработки, предупреждение будет включено в список ошибок при перезаписи файла.

Настройка процесса сборки

Преобразование текста производится перед выполнением других задач в процессе сборки. Задачи, которые вызываются до и после преобразования, можно задавать, устанавливая свойства $(BeforeTransform) и $(AfterTransform).

<PropertyGroup>
    <BeforeTransform>CustomPreTransform</BeforeTransform>
    <AfterTransform>CustomPostTransform</AfterTransform>
</PropertyGroup>
<Target Name="CustomPreTransform">
    <Message Text="In CustomPreTransform..." Importance="High" />
</Target>
<Target Name="CustomPostTransform">
    <Message Text="In CustomPostTransform..." Importance="High" />
</Target>

В свойстве AfterTransform можно указывать списки файлов:

  • GeneratedFiles – список файлов, сгенерированных данным процессом. Для тех файлов, которые перекроют существующие файлы, доступные только для чтения, %(GeneratedFiles.ReadOnlyFileOverwritten) будут иметь значение true. Эти файлы можно извлекать из системы управления версиями.

  • NonGeneratedFiles – список доступных только для чтения файлов, которые не были перезаписаны.

Например, можно определить задачу для извлечения GeneratedFiles.

OutputFilePath и OutputFileName

Эти свойства используются только в MSBuild. Они не влияют на создание кода в Visual Studio. Они перенаправляют созданный выходной файл в другую папку или файл. Целевая папка должна уже существовать.

<ItemGroup>
  <None Include="MyTemplate.tt">
    <Generator>TextTemplatingFileGenerator</Generator>
    <OutputFilePath>MyFolder</OutputFilePath>
    <LastGenOutput>MyTemplate.cs</LastGenOutput>
  </None>
</ItemGroup>

Полезная папка для перенаправления $(IntermediateOutputPath).

Если указать имя выходного файла, оно имеет приоритет над расширением, указанным в директиве выходных данных в шаблонах.

<ItemGroup>
  <None Include="MyTemplate.tt">
    <Generator>TextTemplatingFileGenerator</Generator>
    <OutputFileName>MyOutputFileName.cs</OutputFileName>
    <LastGenOutput>MyTemplate.cs</LastGenOutput>
  </None>
</ItemGroup>

Указание outputFileName или OutputFilePath не рекомендуется, если вы также преобразуете шаблоны внутри Visual Studio с помощью преобразования All или запуска генератора одного файла. В конечном итоге вы будете использовать различные пути к файлам в зависимости от того, как вы активировали преобразование. Это может быть запутано.

Добавление ссылок и путей включения

Узел имеет набор путей по умолчанию, по которым производится поиск сборок, указанных в шаблонах. Для добавления в этот набор:

<ItemGroup>
    <T4ReferencePath Include="$(VsIdePath)PublicAssemblies\" />
    <!-- Add more T4ReferencePath items here -->
</ItemGroup>

Чтобы задать папки, в которых будет производиться поиск включаемых файлов, укажите список через точку с запятой. Обычно производится добавление в существующий список папок.

<PropertyGroup>
    <IncludeFolders>
$(IncludeFolders);$(MSBuildProjectDirectory)\Include;AnotherFolder;And\Another</IncludeFolders>
</PropertyGroup>

Передача данных контекста сборки в шаблоны

Можно задать значения параметров в файле проекта. Например, можно передать свойства сборки и переменные среды:

<ItemGroup>
  <T4ParameterValues Include="ProjectFolder">
    <Value>$(ProjectDir)</Value>
    <Visible>false</Visible>
  </T4ParameterValues>
</ItemGroup>

В текстовом шаблоне задайте атрибут hostspecific в директиве template. Используйте директиву параметра для получения значений:

<#@template language="c#" hostspecific="true"#>
<#@ parameter type="System.String" name="ProjectFolder" #>
The project folder is: <#= ProjectFolder #>

В обработчике директив можно вызвать ITextTemplatingEngineHost.ResolveParameterValue:

string value = Host.ResolveParameterValue("-", "-", "parameterName");

Примечание.

ResolveParameterValue получает данные только при T4ParameterValues использовании MSBuild. При преобразовании шаблона с помощью Visual Studio параметры имеют значения по умолчанию.

Использование свойств проекта в сборке и директивах include

Макросы Visual Studio, такие как $(SolutionDir), не работают в MSBuild. Вместо этого можно использовать свойства проекта.

Измените CSPROJ или VBPROJ-файл , чтобы определить свойство проекта. В этом примере определяется свойство myLibFolder:

<!-- Define a project property, myLibFolder: -->
<PropertyGroup>
    <myLibFolder>$(MSBuildProjectDirectory)\..\libs</myLibFolder>
</PropertyGroup>

<!-- Tell the MSBuild T4 task to make the property available: -->
<ItemGroup>
    <T4ParameterValues Include="myLibFolder">
      <Value>$(myLibFolder)</Value>
    </T4ParameterValues>
  </ItemGroup>

Теперь можно использовать ваше свойство проекта в директивах assembly и include:

<#@ assembly name="$(myLibFolder)\MyLib.dll" #>
<#@ include file="$(myLibFolder)\MyIncludeFile.t4" #>

Эти директивы получают значения из T4parameterValues как в узлах MSBuild, так и в узлах Visual Studio.

Вопросы и ответы

Почему нужно преобразовать шаблоны на сервере сборки? Я уже преобразовал шаблоны в Visual Studio, прежде чем проверка в коде.

При обновлении включенного файла или другого файла, считываемого шаблоном, Visual Studio не преобразует файл автоматически. Преобразование шаблонов в рамках сборки гарантирует, что все актуально.

Какие другие параметры существуют для преобразования текстовых шаблонов?

  • В шаблоне T4 MSbuild есть хорошее руководство. %ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\TextTemplating\Microsoft.TextTemplating.targets
  • В шаблоне T4 MSbuild есть хорошее руководство. %ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\msbuild\Microsoft\VisualStudio\v16.0\TextTemplating\Microsoft.TextTemplating.targets