Заставить Visual Studio запускать шаблон T4 для каждой сборки

Как получить шаблон T4 для генерации его вывода на каждой сборке? Как и сейчас, он только восстанавливает его, когда я делаю изменения в шаблоне.

Я нашел другие вопросы, похожие на этот:

преобразование T4 и порядок сборки в Visual Studio (без ответа)

как получить файлы t4 для сборки в visual studio? (ответы недостаточно детализированы [при этом все еще достаточно сложны] и даже не делают всего смысл)

там должен быть более простой способ сделать это!

19 ответов


я использовал ответ JoelFan на ж/ это. Мне это нравится больше, потому что вам не нужно помнить об изменении события pre-build каждый раз, когда вы добавляете новое .TT файл для проекта.

  • добавить TextTransform.exe в %PATH%
  • создан пакетный файл с именем transform_all.bat (см. ниже)
  • создать событие предварительной сборки"transform_all ..\.."

transform_all.летучая мышь!--15-->

@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

Я согласен с GarethJ-в VS2010 намного проще регенерировать шаблоны tt для каждой сборки. Блог Олега Сыча описывает, как это сделать. Короче:

  1. установить Visual Studio SDK
  2. установить Моделирование Visual Studio 2010 и визуализация SDK
  3. открыть в текстовом редакторе файл проекта и добавить в конец файла, но перед </Project>

вот именно. Откройте свой проект. На каждом строят все *.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" />

существует отличный пакет NuGet, который делает именно это:

PM> Install-Package Clarius.TransformOnBuild

подробная информация о пакете может быть найти здесь


я использовал ответ MarkGr и разработал это решение. Сначала создайте пакетный файл RunTemplate.летучая мышь!--4--> в отдельную инструменты папка над основной папкой решения. Пакетный файл имеет только строку:

"%CommonProgramFiles%\Microsoft Shared\TextTemplating.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt

этот пакетный файл принимает 2 параметра... %1 является путь к.TT файл без .расширение tt. %2 - это путь к любым библиотекам DLL, на которые ссылается сборка директивы в шаблон.

Далее перейдите в свойства проекта проекта, содержащего шаблон T4. Идите в События Построения и добавьте следующий элемент Командная строка события Pre-build:

$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)

замена MyTemplate С именем файла вашего .TT файл (т. е. MyTemplate.tt) без .расширение tt. Это будет иметь результат расширения шаблона для создания MyTemplate.CS, перед построением проекта. После фактической сборки скомпилировать шаблон mytemplate.cs


недавно нашел этот отличный плагин VS,веселый.

Он не только генерирует ваш T4 в сборке, но и позволяет использовать подход на основе T4 для минимизации javascript, CSS и даже позволяет использовать меньше синтаксиса для вашего CSS!


предварительная сборка может быть сведена к одной строке:

forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating.2\TextTransform.exe\" @file"

это превращает все .tt файлов проекта и списки их построения.

если вы не хотите вывод сборки, вам нужно обойти некоторые "интересное поведение":

forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating.2\TextTransform.exe\" @file"

конечно, вы можете вытащить это в пакетный файл, к которому вы передаете путь к каталогу проекта, если хотите.

NB путь может потребовать тонкая настройка. Путь выше, где VS 2008 установил его на моей машине; но вы можете найти, что номер версии между TextTemplating и TextTransform.exe разное.


вероятно, самый простой способ-установить расширение Visual Studio под названием AutoT4.

он запускает все шаблоны T4 на сборке автоматически.


проверить Файлы C:\Program (х86) Общие файлы\\Microsoft общий\TextTemplating там есть преобразование командной строки exe. Также можно написать задачу MSBuild с пользовательским хозяина и преобразования себя.


расширения Сэт Рено и JoelFan это ответы, я придумал это. С помощью этого решения не нужно помнить, чтобы изменить событие предварительной сборки каждый раз при добавлении нового .TT файл для проекта.

Порядок Выполнения

  • создайте пакетный файл с именем transform_all.bat (см. ниже)
  • создать событие предварительной сборки transform_all.bat "$(ProjectDir)" $(ProjectExt) для каждого проекта с a .tt вы хотите build

transform_all.летучая мышь!--23-->

@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.2\
) else (
  echo 64-bit OS detected
  set ttPath=%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating.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


Примечания

  1. преобразование текста предполагает, что код в шаблоне T4 является тем же языком, что и тип проекта. Если этот случай не относится к вам, то вам придется заменить


при использовании Visual Studio 2010 можно использовать пакет SDK для моделирования и визуализации Visual Studio: http://code.msdn.microsoft.com/vsvmsdk

содержит задачи msbuild для выполнения шаблонов T4 во время сборки.

посмотрите блог Олега для получения дополнительных объяснений: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration


Привет, мой скрипт также может анализировать выходное расширение

for /r %1 %%f in (*.tt) do (
 for /f "tokens=3,4 delims==, " %%a in (%%f) do (
  if %%~a==extension "%CommonProgramFiles%\Microsoft Shared\TextTemplating.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) событие предварительной сборки и все *.файлы tt в вашем решении будут автоматически преобразованы.


"Динамо".AutoTT сделает то, что вам нужно. Вы можете настроить его для просмотра файлов через регулярное выражение или создания при сборке. Он также позволяет вам указать, какие шаблоны T4 вы хотите запустить.

вы можете скачать его здесь:https://github.com/MartinF/Dynamo.AutoTT

просто создайте его, скопируйте dll и добавьте файлы в

C:\Users\Documents\Visual Studio 2012\Addins\

и вы уходите.

Если вы хотите получить его идя в VS2012 вам нужно будет модифицировать Динамо.AutoTT.Добавьте файл и установите версию в 11.0 внутри файла добавления;


еще одна хорошая статья на этот: генерация кода в процессе сборки

2012 моделирование и визуализация SDK ссылка для скачивания:

https://www.microsoft.com/en-us/download/details.aspx?id=30680


пожалуйста, смотрите ответ mhutch https://stackoverflow.com/a/1395377/9587

IMHO, это лучший сервер сборки и dev среды дружественный вариант.


вот мое решение-аналогично принятому ответу. У нас были проблемы с системой управления версиями. Цель. cs-файлы доступны только для чтения, и T4 не удалось. Вот код, который запускает T4 во временной папке, сравнивает целевые файлы и копирует их только в случае тех же изменений. Это не устраняет проблему с read.только файлы, но по крайней мере это происходит не очень часто:

трансформировать.летучая мышь!--3-->

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.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.0\TextTransform.exe"  "%ttFile%"
) ELSE (
 ECHO  no change in %csFile%
)

del %tempTT%
del %tempCS%
goto :eof

:End

вы можете попробовать добавить команду check-out в строку (:: вы можете попробовать ....)

в свой проект это как готовую действий:

Path-To-Transform.bat "$(ProjectDir)"

вам просто нужно добавить эту команду к событию предварительной сборки проекта:

if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe  /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets"  $(ProjectPath) /t:TransformAll 

проверка на configuration = debug, гарантирует, что вы не регенерируете код в режиме выпуска, когда вы делаете сборку на сервере сборки TFS, например.


в visual studio 2013 щелкните правой кнопкой мыши шаблон T4 и установите для свойства transform on build значение true.


какой-то парень построил пакет nuget для этого.

Примечание: я получаю ошибки компиляции из обоих TextTemplate.exe и пакете (потому что пакет звонков TextTemplate.exe), но не из Visual Studio. Таким образом, по-видимому, поведение не то же самое; головы вверх.

EDIT:этой в конечном итоге это моя проблема.


вот как я его приколол. ссылке. В основном здание поверх большого блога( blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ не могу опубликовать больше, чем 2 ссылки : () я придумал это .цели файл для использования с файлами Visual studio proj.

это полезно, когда вы используете другие dll-s внутри вашего .tt и вы хотите, чтобы результат изменился, поскольку dll-s изменение.

как работает:

  1. создайте tt, добавьте имя сборки= " $(SolutionDir)path\to\other\project\output\foo.dll и настроить преобразование и результат, чтобы быть, как ожидалось
  2. удалить ссылки на сборки от .ТТ

  3. внутри файла proj используйте этот код для настройки преобразования при сборке:

    <PropertyGroup>
      <!-- Initial default value -->
      <_TransformExe>$(CommonProgramFiles)\Microsoft Shared\TextTemplating.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.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe</_TransformExe>
      <!-- Future proof 'til VS2013+2 -->
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe</_TransformExe>
      <_TransformExe Condition="!Exists('$(_TransformExe)')">$(CommonProgramFiles)\Microsoft Shared\TextTemplating.0\TextTransform.exe</_TransformExe>
    
      <IncludeForTransform>@(DllsToInclude, '&amp;quot; -r &amp;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="&quot;$(_TransformExe)&quot; &quot;@(_TextTransform)&quot; -r &quot;$(IncludeForTransform)&quot;" 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"

  4. в единственное, что осталось сделать, это добавить пути к 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