Obter Visual Studio para executar um modelo de T4 em cada compilação
-
22-07-2019 - |
Pergunta
Como faço para obter um modelo de T4 para gerar sua saída em cada compilação? Como é agora, ele só regenera-lo quando eu fazer uma mudança para o modelo.
Eu encontrei outras questões semelhantes a esta:
T4 transformação e ordem de construção no Visual Studio ( sem resposta)
Como obter arquivos t4 para construir no Visual estúdio? (respostas não são detalhadas o suficiente [enquanto ainda está sendo muito complicada] e nem sequer faz sentido total)
Não tem que ser uma maneira simples de fazer isso!
Solução
Eu usei a resposta de JoelFan para chegar w / este. Eu gosto é melhor porque você não tem que se lembrar de modificar o evento pré-compilação cada vez que você adicionar um novo arquivo .tt ao projeto.
- adicionar TextTransform.exe ao seu
%PATH%
- criado um arquivo de lote chamado transform_all.bat (veja abaixo)
- criar um evento de pré-compilação "
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
Outras dicas
Eu concordo com GarethJ - em VS2010 é muito mais fácil para modelos de tt Regenerar em cada construção. O blog de Oleg Sych descreve como fazê-lo. Em suma:
- Instale Visual Studio SDK
- Instale Visual Studio 2010 Modeling e Visualização SDK
- Abrir no arquivo de projeto editor de texto e
adicionar ao final do arquivo, mas antes
</Project>
É isso. Abra seu projeto. Em cada compilação todos os modelos * .tt será reprocessado
<!-- 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" />
Há um grande pacote NuGet que faz exatamente isso:
PM> Install-Package Clarius.TransformOnBuild
Detalhes sobre o pacote pode ser encontrada aqui
Eu usei a resposta de Markgr e desenvolveu esta solução. Primeiro, crie um arquivo de lote chamado RunTemplate.bat em separado Ferramentas pasta acima da pasta de solução principal. O arquivo de lote só tem a linha:
"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt
Este arquivo de lote leva 2 parâmetros ... % 1 é o caminho para o arquivo .tt sem a extensão .tt. % 2 é o caminho para qualquer DLLs referido por Assembleia directivas no modelo.
Em seguida, vá para as Propriedades do projeto do projeto que contém o modelo T4. Vá para Build Events e adicione a seguinte linha de comando evento Pré-build :
$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)
substituir MyTemplate com nome do seu arquivo .tt (ou seja MyTemplate.tt) sem a extensão .tt. Isto terá o resultado da expansão do modelo para MyTemplate.cs produzir antes de construir o projeto. Em seguida, a compilação real irá compilar MyTemplate.cs
Recentemente encontrei este grande plug-in VS, Chirpy .
Não só gerar o seu T4 em uma compilação, mas permite abordagem baseada-T4 para minification de javascript, CSS, e ainda permite que você use a sintaxe menos para o seu CSS!
Provavelmente a maneira mais simples é instalar uma extensão do Visual Studio chamado AutoT4 .
Ele é executado todos os modelos T4 em construção automagicamente.
O pré-build pode ser reduzida a uma única linha:
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Isso transforma todos os arquivos .tt
no projecto e apresenta-os à saída da compilação.
Se você não quiser que a saída da compilação, em seguida, você tem que trabalhar em torno de alguns "comportamento interessante" :
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
É claro, você pode puxar isto em um arquivo de lote para o qual você passar o caminho diretório do projeto, se desejar.
Nota ??strong> O caminho pode exigir alguns ajustes. O caminho acima é onde VS 2008 instalado na minha máquina; mas você pode achar que o número da versão entre TextTemplating
e TextTransform.exe
é diferente.
Confira C: \ Program Files (x86) \ Arquivos comuns \ Microsoft Shared \ TextTemplating há um comando de linha de transformação exe lá. Alternativamente escrever uma tarefa MSBuild com uma série de costume e fazer o mesmo transformar.
Seth Reno e respostas de JoelFan, eu vim com isso. Com esta solução não precisa se lembrar de modificar o evento pré-compilação cada vez que você adicionar um novo arquivo .tt ao projeto.
Implementação Regimento
- Criar um arquivo de lote transform_all.bat chamado (veja abaixo)
- Criar um
transform_all.bat "$(ProjectDir)" $(ProjectExt)
evento de pré-compilação para cada projeto com um .tt você quer construir
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
NOTAS
-
A transformação de texto assume o código no modelo T4 é a mesma linguagem como o tipo de projeto. Se este caso não se aplica a você, então você terá que substituir o argumento
$(ProjectExt)
com a extensão dos arquivos que você deseja o código de gerar. -
arquivos
.TT
deve estar no diretório do projeto então eles não vão construir. Você pode construir arquivos TT fora do diretório do projeto, especificando um caminho diferente como o primeiro argumento ( i. substituir"$(ProjectDir)"
com o caminho que contém os arquivos do TT.) -
Lembre-se também para definir o caminho correto para o arquivo de lote
transform_all.bat
.
Por exemplo, eu coloquei no meu diretório solução para que o evento pré-compilação foi a seguinte"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)
Se você estiver usando Visual Studio 2010, você pode usar o Visual Studio Modelação e Visualização SDK: http://code.msdn.microsoft.com/vsvmsdk
Este contém tarefas msbuild para a execução de modelos T4 em tempo de compilação.
Tenha um olhar no blog de Oleg para mais explicações: http://www.olegsych.com/2010/04/understanding-t4 -msbuild-integração
Ei, meu script pode extensão de saída também de análise
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%
Basta criar transform_all.bat $(SolutionDir)
evento pré-compilação, e todos os arquivos * .tt em sua solução será transformada de forma automática.
Dynamo.AutoTT vai fazer o que você precisa. Você pode configurá-lo para assistir a ficheiros através de um regex ou gerar em construção. Ele também permite que você especifique qual T4 modelos que você quer que ele gatilho.
Você pode baixá-lo aqui: https://github.com/MartinF/Dynamo.AutoTT
Apenas construí-lo, copiar arquivos DLL e AddIn em
C: \ Users \ Documents \ Visual Studio 2012 \ Addins \
e você vai longe.
Se você quiser ir buscá-la no VS2012 você precisará modificar o arquivo Dynamo.AutoTT.AddIn e definir a versão para 11,0 dentro do arquivo de suplemento;
Aqui está a minha solução - semelhante à resposta aceita. Tivemos um problema com o nosso controle de origem. arquivos do alvo cs são somente leitura eo T4 estava falhando. Aqui está o código, que é executado T4 na pasta temp, compara arquivos de destino e copia-o apenas em caso de mesma mudança. Ele não corrige o problema com arquivos read.only, mas pelo menos ela não ocorre com muita frequência:
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
Você pode tentar adicionar o seu comando check-out em uma linha (:: Você pode tentar ....)
Em seu projeto definir esta como uma ação prebuild:
Path-To-Transform.bat "$(ProjectDir)"
Você só precisa adicionar este comando para o evento pré-compilação do projeto:
if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" $(ProjectPath) /t:TransformAll
A verificação da configuração = debug, garante que você não se regeneram o código no modo de versão, quando você faz a compilação no servidor TFS construir, por exemplo.
No visual studio 2013, clique direito no modelo de T4 e definir a transformação na propriedade de construção para true.
Aqui está como eu pregado isso. Fazer a ligação. Basicamente construir em cima de um grande blog (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ não pode postar mais que 2 ligações :() Eu vim com essa href="https://github.com/gparlakov/TTTransformonBuild/blob/master/TextTemplatingOnBuild.targets" rel="nofollow noreferrer"> .targets arquivo
É útil quando você estiver usando outro dll-s dentro do seu .tt e você quer o resultado a mudança como os dll-s estão mudando. Como funciona: Remova as referências de montagem de .tt Dentro do uso de arquivo proj este código para definir se transformar em construção: A primeira parte Localiza TextTransform.exe A única coisa que resta a fazer é adicionar os caminhos para as DLLs dentro de: Aqui couros Então, agora você deve ser capaz de gerar o seu código na construção e na mudança de dll-s. Você pode remover a ferramenta personalizada (de propriedades dentro do Visual Studio) para que o VS não tenta transformar e falhar miseravelmente todas as vezes. Porque removeu as referências de montagem na etapa 2
<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>
$(IncludeForTransform)
será igual ao c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll
porque essa é a maneira de adicionar referências para o TextTransform na linha de comando <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" />
this cria uma lista de todos os arquivos de tt dentro do projeto e subdiretórios <Exec Command="...
produz uma linha para cada um dos constatada .tt arquivos que se parece com "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.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>
esses itens a partir da solução Ver
T4Executer faz isso para VS2019. Você pode especificar modelos de ignorar em construção, e há uma executar opção de compilação depois.
um cara construiu um NuGet pacote para isso.
Nota lateral: eu recebo erros de compilação de ambos TextTemplate.exe e aquele pacote (porque esse pacote chama TextTemplate.exe), mas não a partir do Visual Studio. Então, aparentemente, o comportamento não é o mesmo; heads-up.
EDIT:. Este acabou sendo meu problema
Você só instalar o NuGet Package: Clarius.TransformOnBuild
Então, cada vez que você clicar em Reconstruir projecto (ou solução), o seu .tt arquivos será executado
No Visual Studio 2017 (provavelmente próximas versões também), você deve adicionar isso em evento pré-compilação:
"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"
P.S. Alterar caminho para o seu modelo, se não é localizado no diretório raiz do projeto.