Получить Visual Studio для запуска шаблона T4 для каждой сборки
Как мне получить шаблон T4 для генерации вывода на каждой сборке? Как и сейчас, он только восстанавливает его, когда я вношу изменения в шаблон.
Я нашел другие вопросы, подобные этому:
Преобразование T4 и порядок сборки в Visual Studio (без ответа)
Как получить файлы t4 для создания в visual studio? (ответы недостаточно подробны [при этом все еще сложны] и даже не дают полного смысла)
Там должен быть более простой способ сделать это!
Ответы
Ответ 1
Я использовал ответ JoelFan, чтобы подойти к этому. Мне это нравится, потому что вам не нужно запоминать, чтобы изменить событие pre-build каждый раз, когда вы добавляете в проект новый файл .tt.
- добавьте TextTransform.exe к вашему
%PATH%
- создал пакетный файл с именем transform_all.bat(см. ниже)
- создать событие предварительной сборки "
transform_all ..\..
"
transform_all.bat
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: set the working dir (default to current dir)
set wdir=%cd%
if not (%1)==() set wdir=%1
:: set the file extension (default to vb)
set extension=vb
if not (%2)==() set extension=%2
echo executing transform_all from %wdir%
:: create a list of all the T4 templates in the working dir
dir %wdir%\*.tt /b /s > t4list.txt
echo the following T4 templates will be transformed:
type t4list.txt
:: transform all the templates
for /f %%d in (t4list.txt) do (
set file_name=%%d
set file_name=!file_name:~0,-3!.%extension%
echo: \--^> !file_name!
TextTransform.exe -out !file_name! %%d
)
echo transformation complete
Ответ 2
Я согласен с GarethJ - в VS2010 гораздо проще регенерировать tt шаблоны для каждой сборки.
Блог Oleg Sych описывает, как это сделать. Короче говоря:
Что это. Откройте свой проект. При каждом создании все шаблоны *.tt будут переработаны
<!-- This line could already present in file. If it is so just skip it -->
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- process *.tt templates on each build -->
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
Ответ 3
Существует большой пакет NuGet, который выполняет только это:
PM> Install-Package Clarius.TransformOnBuild
Информация о пакете может быть найдена здесь
Ответ 4
Я использовал ответ MarkGr и разработал это решение. Сначала создайте пакетный файл RunTemplate.bat в отдельной папке tools над основной папкой решения. Пакетный файл имеет только строку:
"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt
Этот командный файл принимает 2 параметра... % 1 - это путь к файлу .tt без расширения .tt. % 2 - это путь к любым DLL, указанным директивами Assembly в шаблоне.
Затем перейдите в Project Properties проекта, содержащего шаблон T4. Перейдите в События сборки и добавьте следующую командную строку Pre-build event:
$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)
заменить MyTemplate на имя файла .tt(т.е. MyTemplate.tt) без расширения .tt. Это приведет к расширению шаблона для создания MyTemplate.cs перед созданием проекта. Тогда фактическая сборка будет компилировать MyTemplate.cs
Ответ 5
Недавно был найден этот отличный плагин VS, Chirpy.
Он не только генерирует ваш T4 в сборке, но и позволяет использовать метод T4 для минимизации javascript, CSS и даже позволяет использовать синтаксис LESS для вашего CSS!
Ответ 6
Вероятно, самым простым способом является установка расширения Visual Studio под названием AutoT4.
Он автоматически запускает все шаблоны T4 при создании.
Ответ 7
Предварительная сборка может быть сведена к одной строке:
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Это преобразует все файлы .tt
в проект и выводит их на вывод сборки.
Если вам не нужен вывод сборки, вам нужно обойти некоторое "интересное поведение" :
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Конечно, вы можете вытащить это в пакетный файл, на который вы передаете путь к каталогу проекта, если хотите.
NB Путь может потребовать некоторой настройки. Путь выше - там, где VS 2008 установлен на моей машине; но вы можете обнаружить, что номер версии между TextTemplating
и TextTransform.exe
отличается.
Ответ 8
Отъезд
C:\Program Files (x86)\Common Files\Microsoft Shared\TextTemplating
там есть трансформация командной строки exe. Альтернативно напишите задачу MSBuild с помощью настраиваемого хоста и сделайте преобразование самостоятельно.
Ответ 9
Развернувшись на Seth Reno и ответы JoelFan, я придумал это. С этим решением не нужно запоминать изменение события предварительной сборки каждый раз, когда вы добавляете в файл новый файл .tt.
Процедура выполнения
- Создайте пакетный файл с именем transform_all.bat(см. ниже)
- Создайте событие pre-build
transform_all.bat "$(ProjectDir)" $(ProjectExt)
для каждого проекта с .tt, который вы хотите создать
transform_all.bat
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: set the correct path to the the app
if not defined ProgramFiles(x86). (
echo 32-bit OS detected
set ttPath=%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\
) else (
echo 64-bit OS detected
set ttPath=%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\
)
:: set the working dir (default to current dir)
if not (%1)==() pushd %~dp1
:: set the file extension (default to vb)
set ext=%2
if /i %ext:~1%==vbproj (
set ext=vb
) else if /i %ext:~1%==csproj (
set ext=cs
) else if /i [%ext%]==[] (
set ext=vb
)
:: create a list of all the T4 templates in the working dir
echo Running TextTransform from %cd%
dir *.tt /b /s | findstr /vi obj > t4list.txt
:: transform all the templates
set blank=.
for /f "delims=" %%d in (t4list.txt) do (
set file_name=%%d
set file_name=!file_name:~0,-3!.%ext%
echo: \--^> !!file_name:%cd%=%blank%!
"%ttPath%TextTransform.exe" -out "!file_name!" "%%d"
)
:: delete T4 list and return to previous directory
del t4list.txt
popd
echo T4 transformation complete
ПРИМЕЧАНИЯ
-
Преобразование текста предполагает, что код в шаблоне T4 является тем же языком, что и ваш тип проекта. Если этот случай не относится к вам, вам придется заменить аргумент $(ProjectExt)
расширением файлов, которые вы хотите генерировать код.
-
.TT
файлы должны находиться в каталоге проекта, иначе они не будут созданы. Вы можете создавать файлы TT вне каталога проекта, указав другой путь в качестве первого аргумента ( i.e. заменить "$(ProjectDir)"
на путь, содержащий файлы TT).
-
Помните также установить правильный путь к пакетному файлу transform_all.bat
.
Например, я поместил его в каталог решений, поэтому событие предварительной сборки было следующим: "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)
Ответ 10
Если вы используете Visual Studio 2010, вы можете использовать Visual Studio Modeling and Visualization SDK:
http://code.msdn.microsoft.com/vsvmsdk
Это содержит задачи msbuild для выполнения шаблонов T4 во время сборки.
Взгляните на блог Олега для более подробного объяснения:
http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration
Ответ 11
Эй,
my script также может анализировать расширение вывода
for /r %1 %%f in (*.tt) do (
for /f "tokens=3,4 delims==, " %%a in (%%f) do (
if %%~a==extension "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %%~pnf.%%~b -P %%~pf -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %%f
)
)
echo Exit Code = %ERRORLEVEL%
Просто создайте событие transform_all.bat $(SolutionDir)
pre-build, и все *.tt файлы в вашем решении будут автоматически преобразованы.
Ответ 12
Dynamo.AutoTT сделает все, что вам нужно. Вы можете настроить его для просмотра файлов с помощью регулярного выражения или генерации при сборке. Он также позволяет указать, какие шаблоны T4 вы хотите вызвать.
Вы можете скачать его здесь: https://github.com/MartinF/Dynamo.AutoTT
Просто создайте его, скопируйте DLL и файлы AddIn в
C:\Users\Documents\Visual Studio 2012\Addins\
и уходите.
Если вы хотите получить его в VS2012, вам нужно будет изменить файл Dynamo.AutoTT.AddIn и установить версию на 11.0 внутри файла Addin;
Ответ 13
См. ответ mhutch fooobar.com/questions/31146/...
IMHO, это лучший сервер сборки и дружественный для разработчиков вариант.
Ответ 14
Еще одна хорошая статья: Генерация кода в процессе сборки
2012 Ссылка на скачивание и скачивание SDK для моделирования и визуализации:
https://www.microsoft.com/en-us/download/details.aspx?id=30680
Ответ 15
Вот мое решение - похоже на принятый ответ.
У нас была проблема с нашим контролем источника. Целевые .cs файлы доступны только для чтения и T4 не работает.
Вот код, который запускает T4 в папке temp, сравнивает целевые файлы и копирует его только в случае одного и того же изменения. Он не исправляет проблему с файлами read.only, но по крайней мере это происходит не часто:
Transform.bat
ECHO Transforming T4 templates
SET CurrentDirBackup=%CD%
CD %1
ECHO %1
FOR /r %%f IN (*.tt) DO call :Transform %%f
CD %CurrentDirBackup%
ECHO T4 templates transformed
goto End
:Transform
set ttFile=%1
set csFile=%1
ECHO Transforming %ttFile%:
SET csFile=%ttFile:~0,-2%cs
For %%A in ("%ttFile%") do Set tempTT=%TEMP%\%%~nxA
For %%A in ("%csFile%") do Set tempCS=%TEMP%\%%~nxA
copy "%ttFile%" "%tempTT%
"%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe" "%tempTT%"
fc %tempCS% %csFile% > nul
if errorlevel 1 (
:: You can try to insert you check-out command here.
"%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe" "%ttFile%"
) ELSE (
ECHO no change in %csFile%
)
del %tempTT%
del %tempCS%
goto :eof
:End
Вы можете попробовать добавить свою команду выписки из строки (:: Вы можете попробовать...)
В вашем проекте установите это как действие предварительной сборки:
Path-To-Transform.bat "$(ProjectDir)"
Ответ 16
Вам просто нужно добавить эту команду в событие предварительной сборки проекта:
if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" $(ProjectPath) /t:TransformAll
Проверка конфигурации = debug, убедитесь, что вы не обновляете код в режиме выпуска, когда вы делаете сборку на сервере сборки TFS, например.
Ответ 17
В visual studio 2013 щелкните правой кнопкой мыши шаблон T4 и установите для свойства transform на build значение true.
Ответ 18
Вот как я это сделал. Ссылка. В основном, основываясь на большом блоге (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/не может публиковать больше, что 2 Ссылки:() Я придумал этот .targets файл для использования с файлами proj с визуальной студией.
Это полезно, когда вы используете другие dll-s внутри вашего .tt и хотите, чтобы результат изменился по мере изменения dll.
Как это работает:
- Создайте tt, добавьте путь сборки name= "$ (SolutionDir)\to\other\project\output\foo.dll и настройте преобразование и результат как ожидалось
-
Удалите ссылки на сборку из .tt
-
Внутри файла proj этот код используется для настройки преобразования при сборке:
<PropertyGroup>
<!-- Initial default value -->
<_TransformExe>$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
<!-- If explicit VS version, override default -->
<_TransformExe Condition="'$(VisualStudioVersion)' != ''">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe</_TransformExe>
<!-- Cascading probing if file not found -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\11.0\TextTransform.exe</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\12.0\TextTransform.exe</_TransformExe>
<!-- Future proof 'til VS2013+2 -->
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\13.0\TextTransform.exe</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\14.0\TextTransform.exe</_TransformExe>
<_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating\15.0\TextTransform.exe</_TransformExe>
<IncludeForTransform>@(DllsToInclude, '&quot; -r &quot;')</IncludeForTransform>
</PropertyGroup>
-
Первая часть находит TextTransform.exe
-
$(IncludeForTransform)
будет равно c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll
, потому что способ добавления ссылок для TextTransform в командной строке
<Target Name="TransformOnBuild" BeforeTargets="BeforeBuild">
<!--<Message Text="$(IncludeForTransform)" />-->
<Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
<ItemGroup>
<_TextTransform Include="$(ProjectDir)**\*.tt" />
</ItemGroup>
<!-- Perform task batching for each file -->
<Exec Command=""$(_TransformExe)" "@(_TextTransform)" -r "$(IncludeForTransform)"" Condition="'%(Identity)' != ''" />
</Target>
-
<_TextTransform Include="$(ProjectDir)**\*.tt" />
это создает список всех файлов tt внутри проекта и подкаталогов
-
<Exec Command="...
выводит строку для каждого найденного файла .tt, который выглядит как "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll"
-
Осталось только добавить пути к dll внутри:
<ItemGroup>
<DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
<InProject>False</InProject>
</DllsToInclude>
<DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
<InProject>False</InProject>
</DllsToInclude>
</ItemGroup>
Здесь <InProject>False</InProject>
скрывает эти элементы из представления решения
Итак, теперь вы сможете сгенерировать свой код при сборке и об изменении dll-s.
Вы можете удалить настраиваемый инструмент (из свойств внутри Visual Studio), чтобы VS не пытался преобразовывать и терпеть неудачу каждый раз. Поскольку мы удалили ссылки на сборку на шаге 2
Ответ 19
T4Executer делает это для VS2019. Вы можете указать шаблоны, которые будут игнорироваться при сборке, и есть опция выполнения после сборки.
Ответ 20
Вы просто устанавливаете пакет NuGet: Clarius.TransformOnBuild
Затем каждый раз, когда вы нажимаете Rebuild project (или Solution), ваши .tt файлы будут запускаться
Ответ 21
Некоторый парень построил пакет nuget для это.
Боковое примечание. Я получаю ошибки компиляции из TextTemplate.exe и этого пакета (потому что этот пакет вызывает TextTemplate.exe), но не из Visual Studio. По-видимому, поведение не одно и то же; вверх.
EDIT: Этот вопрос оказался моей проблемой.
Ответ 22
В Visual Studio 2017 (возможно, и в следующих версиях) вы должны добавить это в событие Pre-build:
"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"
ps Измените путь к вашему шаблону, если он находится не в корневом каталоге проекта.
Ответ 23
У меня была ситуация, когда мне нужно запустить только шаблон .t T4 в сборке проекта. Ни один из ответов не описывает выборочное выполнение шаблонов T4, ниже в статье рассматривается полная конфигурация для
- Автоматический запуск шаблона T4 при сборке/перестройке проекта или решения
- Показать сообщения до и после преобразования в окне вывода
- Журнал список файлов, затронутых этим
- Настройте для запуска всех шаблонов или только определенных.
Как автоматически запустить пользовательский инструмент для шаблонов T4
Ответ 24
Благодаря GitHub.com/Mono/T4 на данный момент вы можете сделать это как для сборок .NET Core, так и для сборок Visual Studio, добавив это в файл .csproj
:
<ItemGroup>
<DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
<TextTemplate Include="**\*.tt" />
</ItemGroup>
<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
<ItemGroup>
<Compile Remove="**\*.cs" />
</ItemGroup>
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
</Target>
Если вы преобразуете свои шаблоны в разные языки программирования, вам нужно добавить что-то вроде <Compile Remove="**\*.vb" />
и <Compile Include="**\*.vb" />
, чтобы эти файлы были скомпилированы, даже если вы еще не сгенерировали файлы.
Трюк Remove
и Include
нужен только для первого поколения, или вы можете сделать XML-код короче, например так:
<ItemGroup>
<DotNetCliToolReference Include="dotnet-t4-project-tool" Version="2.0.5" />
<TextTemplate Include="**\*.tt" />
</ItemGroup>
<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet t4 %(TextTemplate.Identity)" />
</Target>
и просто запустите build дважды (в первый раз). Если вы уже сгенерировали файлы, зафиксированные в репозитории, не будет проблем при перестроениях в обоих примерах.
В Visual Studio вы можете захотеть увидеть что-то вроде этого:
![enter image description here]()
вместо этого:
![enter image description here]()
Поэтому добавьте что-то подобное в файл проекта:
<ItemGroup>
<Compile Update="UInt16Class.cs">
<DependentUpon>UInt16Class.tt</DependentUpon>
</Compile>
<Compile Update="UInt32Class.cs">
<DependentUpon>UInt32Class.tt</DependentUpon>
</Compile>
<Compile Update="UInt64Class.cs">
<DependentUpon>UInt64Class.tt</DependentUpon>
</Compile>
<Compile Update="UInt8Class.cs">
<DependentUpon>UInt8Class.tt</DependentUpon>
</Compile>
</ItemGroup>
Полный пример здесь: GitHub.com/Konard/T4GenericsExample (включает создание нескольких файлов из одного шаблона).