Faça com que o Visual Studio execute um modelo T4 em cada compilação

163

Como obtenho um modelo T4 para gerar sua saída em cada build? Como é agora, ele só a regenera quando faço uma alteração no modelo.

Eu encontrei outras perguntas semelhantes a esta:

Transformação T4 e ordem de compilação no Visual Studio (sem resposta)

Como obter arquivos t4 para criar no visual studio? (as respostas não são detalhadas o suficiente [embora ainda sejam bastante complicadas] e nem fazem todo o sentido)

Tem que haver uma maneira mais simples de fazer isso!

JoelFan
fonte
Embora eu esteja pessoalmente interessado em ouvir uma resposta para isso, qual é o seu cenário específico? Normalmente, a saída do modelo deve ser apenas uma função da entrada; portanto, gerar alterações é bom.
Pavel Minaev 29/10/09
6
Meu modelo usa reflexão para examinar outros assemblies, que podem ter sido alterados desde a última compilação.
JoelFan 29/10/2009
E sobre essa idéia: stackoverflow.com/questions/1649649/...
JoelFan
Meu modelo serve a um propósito: registrar a hora da data de construção.
Scott Solmer

Respostas:

68

Eu usei a resposta de JoelFan para chegar a isso. Eu gosto mais porque você não precisa se lembrar de modificar o evento de pré-construção toda vez que adicionar um novo arquivo .tt ao projeto.

  • adicione TextTransform.exe ao seu %PATH%
  • criou um arquivo em lote chamado transform_all.bat (veja abaixo)
  • crie um evento de pré-construçã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
Seth Reno
fonte
28
Ótima solução. Eu preferi colocar o caminho completo para TextTransform.exe ( "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe") no arquivo de lote, em vez de adicioná-lo para% PATH%
Adam Nofsinger
20
Uma variável melhor seria% COMMONPROGRAMFILES (x86)% em vez de% COMMONPROGRAMFILES%, pois também funcionaria em um sistema de 64 bits.
Durden81
3
Então o caminho completo será %COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe. Coloque-o entre aspas duplas.
Northben
1
@ piers7: atualizei o código para detectar automaticamente a 'bitness' do sistema operacional que está executando o script. Também incluí o comentário da northben para pular o diretório obj e implementei a preferência de Adam Nofsinger em não modificar a variável de ambiente% PATH%.
Alex Essilfie
1
IMHO ter que fornecer o caminho para a TextTransform.exemerda. Você já pode clicar com o botão direito do mouse em "Executar ferramenta personalizada" no Visual Studio, para que ele já tenha o caminho da ferramenta. Por que tenho que passar pelo trabalho de fornecê-lo novamente quando estou construindo a partir de um contexto do Visual Studio?
Jez
70

Eu concordo com o GarethJ - no VS2010, é muito mais fácil regenerar os modelos tt em cada build. O blog de Oleg Sych descreve como fazê-lo. Em resumo:

  1. Instale o Visual Studio SDK
  2. Instale o SDK de modelagem e visualização do Visual Studio 2010
  3. Abra no arquivo de projeto do editor de texto e inclua no final do arquivo, mas antes </Project>

É isso aí. Abra seu projeto. Em cada build, todos os modelos * .tt serão reprocessados

<!-- 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" />
Cheburek
fonte
2
Aqui está um link para postagem do blog de Oleg Sych: olegsych.com/2010/04/understanding-t4-msbuild-integration
PhilChuang
4
Esta é uma solução muito boa. No entanto, existe uma maneira de fazer isso funcionar sem exigir a instalação dos SDKs? Eu tenho tentado fazê-lo funcionar copiando os arquivos .targets e os assemblies relacionados, mas sem sucesso.
Grimus
3
O Chirpy parece funcionar sem precisar fazer o download de SDKs ... no entanto, você ainda precisa fazer o download e configurar o Chirpy. Ainda estou tentando descobrir uma solução que funcione em uma instalação padrão do VS2010 e esteja disponível no repositório de origem, para que os desenvolvedores precisem apenas verificar o repositório para que ele funcione. Todas essas outras soluções exigem muita atenção por desenvolvedor.
Mir
1
Se você criar seus projetos usando a versão x64 do MSBuild - você receberá este erro: 'MSB4019: O projeto importado "C: \ Arquivos de Programas (x86) \ MSBuild \ Microsoft \ VisualStudio \ TextTemplating \ v10.0 \ Microsoft.TextTemplating.targets " não foi encontrado.' erro. Solução alternativa - substitua a variável $ (MSBuildExtensionsPath) por $ (MSBuildExtensionsPath32) em um arquivo de projeto.
Rusted
3
Além disso, você não precisa corrigir os arquivos .csproj. A partir da linha de comando, chame algo como msbuild mySolution.sln /p:CustomAfterMicrosoftCommonTargets="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" /p:TransformOnBuild=true /p:TransformOutOfDateOnly=false
Giulio Vian
29

Existe um ótimo pacote NuGet que faz exatamente isso:

PM> Install-Package Clarius.TransformOnBuild

Detalhes sobre o pacote podem ser encontrados aqui

GavKilbride
fonte
2
Há um garfo 'não oficial': nuget.org/packages/Clarius.TransformOnBuild-unofficial que suportes contentconstruir ações
Erno
1
É bom extensão, mas ele está correndo TextTransform.exe no modo commandLine, então hostspecific = "true" funcions vontade não trabalho
Gh61
1
@JenishRabadiya Adicione esta linha ao topo do modelo:<#@ template language="C#" #>
Peter van Kekem
2
Parece que o pacote foi atualizado para oferecer suporte a hostspecific = "true" e outros problemas (8 dias atrás)
Mingwei Samuel
1
A ação de criação de conteúdo está funcionando agora com a versão mais recente.
precisa saber é o seguinte
20

Usei a resposta do MarkGr e desenvolvi esta solução. Primeiro, crie um arquivo em lotes chamado RunTemplate.bat em uma pasta de ferramentas separada acima da pasta principal da solução. O arquivo em lotes tem apenas 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 em lotes usa 2 parâmetros ... % 1 é o caminho para o arquivo .tt sem a extensão .tt. % 2 é o caminho para as DLLs mencionadas pelas diretivas Assembly no modelo.

Em seguida, acesse as Propriedades do projeto que contém o modelo T4. Acesse Build Events e adicione a seguinte linha de comando do evento Pre-build :

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

substituindo MyTemplate pelo nome do arquivo .tt (ou seja, MyTemplate.tt) sem a extensão .tt. Isso resultará na expansão do modelo para produzir MyTemplate.cs antes da criação do projeto. Em seguida, a compilação real compilará o MyTemplate.cs

JoelFan
fonte
embora eu ainda tenha o problema: stackoverflow.com/questions/1669893/…
JoelFan 3/11/2009
1
Não esqueça as aspas em torno de $ (SolutionDir) .. \ .. \ tools \ RunTemplate.bat
Ewald Hofman
14

Recentemente, encontrei este ótimo plug-in do VS, Chirpy .

Ele não apenas gera seu T4 em uma compilação, mas permite uma abordagem baseada em T4 para minificação de javascript, CSS e ainda permite que você use menos sintaxe para seu CSS!

Mark Melville
fonte
13

Provavelmente, a maneira mais simples é instalar uma extensão do Visual Studio chamada AutoT4 .

Ele executa todos os modelos T4 na construção automagicamente.

Saul
fonte
Acordado! Configurável e funciona com o VS 2015. Ele ainda suporta o uso do assembly EnvDTE (para obter a configuração da compilação), o que nem todos os métodos fazem. A única desvantagem é que todos os membros da equipe precisam instalar a extensão.
Gyromite
12

A pré-construção pode ser reduzida para 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 .ttarquivos no projeto e os lista na saída da compilação.

Se você não quiser a saída da compilação, precisará contornar algum "comportamento interessante" :

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

Obviamente, você pode extrair isso para um arquivo em lotes para o qual passa o caminho do diretório do projeto, se desejar.

NB O caminho pode exigir alguns ajustes. O caminho acima é onde o VS 2008 o instalou na minha máquina; mas você pode achar que o número da versão entre TextTemplatinge TextTransform.exeé diferente.

Peter Taylor
fonte
@SprintStar, se você tem o VS 2012, provavelmente existe uma maneira melhor de fazê-lo. Outras respostas falar sobre as melhores formas já existentes para VS 2010.
Peter Taylor
Este é o melhor método, porque não preciso instalar nada.
Ryan Gates
1
Vi que não havia 1.2, mas havia um 12.0, então mudei para isso, mas obtive este erro:System.Exception: T4MVC can only execute through the Visual Studio host
colmde 15/03
1
Só tive que atualizar o caminho da pasta para usar 14.0 em vez de 1.2 e pronto.
Pistol-pete #
Esta foi a melhor solução na minha opinião (apenas alterando 14.0, como mencionado acima) #
Nelson Rodriguez
9

Confira C: \ Arquivos de programas (x86) \ Arquivos comuns \ Microsoft Shared \ TextTemplating. Existe um exe de transformação de linha de comando. Como alternativa, escreva uma tarefa do MSBuild com um host personalizado e faça a transformação por conta própria.

MarkGr
fonte
1
Ah, embora você possa fazer coisas como "devenv / Command TextTransformation.TransformAllTemplates / Command File.Exit MySolution.sln" em 2010, ele tende a quebrar ocasionalmente em servidores de compilação. Sua melhor aposta é escrever uma tarefa do MSBuild com um host personalizado.
Markgr
Para compilações de área de trabalho, basta criar uma macro que faça um TransformAllTemplates e, em seguida, uma compilação.
Markgr
7

Expandindo em Seth Reno e as respostas de JoelFan , eu vim com isso. Com esta solução, não é necessário lembrar-se de modificar o evento de pré-construção toda vez que você adicionar um novo arquivo .tt ao projeto.

Procedimento de Implementação

  • Crie um arquivo em lote chamado transform_all.bat (veja abaixo)
  • Crie um evento de pré-construção transform_all.bat "$(ProjectDir)" $(ProjectExt)para cada projeto com um .tt que você deseja criar

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

  1. A transformação de texto assume que o código no modelo T4 é o mesmo idioma que o seu tipo de projeto. Se esse caso não se aplicar a você, será necessário substituir o $(ProjectExt)argumento pela extensão dos arquivos que você deseja que o código gere.

  2. .TTos arquivos devem estar no diretório do projeto, caso contrário não serão construídos. Você pode construir arquivos TT fora do diretório do projeto, especificando um caminho diferente como o primeiro argumento ( ou seja, substituir"$(ProjectDir)" pelo caminho que contém os arquivos TT).

  3. Lembre-se também de definir o caminho correto para o transform_all.batarquivo em lotes.
    Por exemplo, coloquei-o no diretório da solução para que o evento de pré-construção fosse o seguinte"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

Alex Essilfie
fonte
Estou tentando usar essa abordagem, mas continuo recebendo um erro com '\ Common foi inesperado no momento'. na minha saída. Isso acontece exatamente nesta linha: para / f "delims =" %% d em (t4list.txt)) faz ... Alguma idéia do que estou perdendo?
Michael Lewis
@ MichaelLewis: Examinei o arquivo em lotes várias vezes sem detectar o que poderia estar causando o erro. Por favor, tente o método proposto por Seth Reno para ver se ele gera o mesmo erro. Enquanto isso, você pode postar seu t4list.txtarquivo no PasteBin para tentar ver se o erro está vindo de lá?
Alex Essilfie
Tentei a abordagem de Seth com o mesmo problema ('\ Common era inesperado no momento'). Não consigo postar o arquivo t4list.txt devido a restrições corporativas, mas ele consiste em uma linha e \ Common não aparece no caminho.
Michael Lewis
@ MichaelLewis: Infelizmente, se o seu erro ocorrer for /f "delims=" %%d in (t4list.txt) do (e as restrições corporativas o impedirem de postar seu t4list.txtarquivo, receio que não haja muito o que fazer para ajudá-lo. Eu realmente queria ajudar a resolver isso, mas parece que será impossível, pois não tenho dados para prosseguir. Boa sorte na solução do problema e lembre-se de postar sua solução quando tiver êxito.
Alex Essilfie
É possível fazer o mesmo quando tt contém (this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;? Infelizmente, recebo uma exceção de referência nula quando executo tt de fora do visual studio.
Andrey K.
4

Ei, meu script também pode analisar a extensão de saída

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)um evento de pré-construção, e todos os arquivos * .tt em sua solução serão transformados automaticamente.

MadRabbit
fonte
3

O Dynamo.AutoTT fará o que você precisa. Você pode configurá-lo para assistir arquivos por meio de um regex ou gerar na compilação. Ele também permite especificar quais modelos T4 você deseja que ele ative.

Você pode fazer o download aqui : https://github.com/MartinF/Dynamo.AutoTT

Apenas construa, copie os arquivos dll e AddIn para

C: \ Usuários \ Documentos \ Visual Studio 2012 \ Addins \

e você vai embora.

Se você deseja colocá-lo no VS2012, precisará modificar o arquivo Dynamo.AutoTT.AddIn e definir a Versão como 11.0 dentro do arquivo AddIn;

Matware
fonte
3

Graças ao GitHub.com/Mono/T4 , no momento você pode fazer isso para compilações do .NET Core e do Visual Studio adicionando isso ao seu .csprojarquivo:

  <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>

Se você transformar seus modelos em diferentes linguagens de programação, adicione algo como <Compile Remove="**\*.vb" />e<Compile Include="**\*.vb" /> para compilar esses arquivos, mesmo que você ainda não tenha gerado arquivos.

Removee Includetruque necessário apenas para a primeira geração, ou você pode tornar o XML mais curto assim:

  <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>

e apenas execute o build duas vezes (pela primeira vez). Se você já gerou arquivos confirmados no repositório, não haverá problemas nas reconstruções com os dois exemplos.

No Visual Studio, você pode querer ver algo assim:

insira a descrição da imagem aqui

em vez disso:

insira a descrição da imagem aqui

Portanto, adicione algo assim ao seu arquivo de projeto:

  <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>

Exemplo completo aqui: GitHub.com/Konard/T4GenericsExample (inclui a geração de vários arquivos a partir de um único modelo).

Konard
fonte
1

Aqui está a minha solução - semelhante à resposta aceita. Tivemos um problema com nosso controle de origem. Os arquivos .cs de destino são somente leitura e o T4 estava falhando. Aqui está o código, que executa o T4 na pasta temp, compara os arquivos de destino e os copia apenas no caso da mesma alteração. Não corrige o problema com os arquivos read.only, mas pelo menos 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 seu comando de check-out em uma linha (:: Você pode tentar ....)

No seu projeto, defina isso como uma ação de pré-construção:

Path-To-Transform.bat "$(ProjectDir)"
Ondra
fonte
1

Você só precisa adicionar este comando ao evento de pré-construçã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 em configuration = debug garante que você não gere novamente o código no modo de liberação, quando você faz a compilação no servidor de compilação do TFS, por exemplo.

anoop
fonte
Bom, mas transformando tudo poderia ser perigoso se T4MVC não só é tt no projeto e nós não queremos correr tudo ...
Landeeyo
3
Não tenho TextTemplating na pasta v11.0. De onde você tira isso?
Zack
1

No visual studio 2013, clique com o botão direito do mouse no modelo T4 e defina a propriedade transform on build para true.

user1607685
fonte
1
Não consigo encontrar essa opção no menu do botão direito, no entanto, de acordo com o MSDN, é possível fazer isso editando o arquivo do projeto no VS 2012 e 2013, consulte msdn.microsoft.com/en-us/library/ee847423. aspx ou msdn.microsoft.com/en-us/library/vstudio/ee847423.aspx para mais detalhes
halb yoel
Parece ser uma opção fornecida apenas com ferramentas T4 tangíveis, não padrão no Visual Studio.
Matt DiTrolio 23/05
Sim, isso é apenas na versão pro do T4 Toolbox.
Pompair
1

Aqui está como eu lidei com isso. Link . Basicamente, construindo sobre um ótimo 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 links :() Eu criei este arquivo .targets para usar com os arquivos de projeção do visual studio.

É útil quando você está usando outras dll-s dentro do seu .tt e deseja que o resultado seja alterado à medida que as dll-s estão sendo alteradas.

Como funciona:

  1. Crie o tt, adicione o nome do assembly = "$ (SolutionDir) path \ to \ other \ project \ output \ foo.dll e configure a transformação e o resultado conforme o esperado
  2. Remova as referências de montagem de .tt

  3. Dentro do arquivo proj, use este código para configurar a transformação na compilação:

    <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, '&amp;quot; -r &amp;quot;')</IncludeForTransform>
    </PropertyGroup>
    • Primeira parte localiza TextTransform.exe

    • $(IncludeForTransform)será igual a, c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dllporque 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="&quot;$(_TransformExe)&quot; &quot;@(_TextTransform)&quot; -r &quot;$(IncludeForTransform)&quot;" Condition="'%(Identity)' != ''" />
       </Target>
    • <_TextTransform Include="$(ProjectDir)**\*.tt" />isso cria uma lista de todos os arquivos tt dentro do projeto e subdiretórios

    • <Exec Command="... produz uma linha para cada um dos arquivos .tt encontrados 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"

  4. A única coisa a fazer é adicionar os caminhos para as dlls dentro de:

        <ItemGroup>
          <DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
            <InProject>False</InProject>
          </DllsToInclude>
          <DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
            <InProject>False</InProject>
          </DllsToInclude>
        </ItemGroup>

    Aqui, <InProject>False</InProject>oculta esses itens da exibição da solução

Portanto, agora você deve poder gerar seu código na compilação e na alteração de dll-s.

Você pode remover a ferramenta personalizada (das propriedades dentro do Visual Studio) para que o VS não tente transformar e falhar miseravelmente todas as vezes. Como removemos as referências de montagem na etapa 2

Georgi
fonte
Por favor, adicione a solução em si à sua resposta para fornecer mais contexto. Os links não são soluções para a pergunta e podem estar mortos quando outros usuários voltarem a essa pergunta posteriormente.
24516 Frank van Wijk em
1

O T4Executer faz isso para o VS2019. Você pode especificar modelos para ignorar na construção, e há uma opção executar após a construção.

Tim Maes
fonte
1

Você acabou de instalar o Pacote NuGet : Clarius.TransformOnBuild

Então, toda vez que você clicar em Reconstruir projeto (ou Solução), seus arquivos .tt serão executados

dqthe
fonte
1

No Visual Studio 2017 (provavelmente também nas próximas versões), você deve adicionar isso no evento Pre-build:

"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"

ps Altere o caminho para o seu modelo se ele não estiver localizado no diretório raiz do projeto.

aleatório
fonte
0

Um cara construiu um pacote de pepitas para isso.

Nota: Recebo erros de compilação do TextTemplate.exe e desse pacote (porque esse pacote chama TextTemplate.exe), mas não do Visual Studio. Então, aparentemente, o comportamento não é o mesmo; Atenção.

EDIT: Este acabou sendo o meu problema.

Grault
fonte
0

Aqui está um evento de pré-construção usando apenas o Microsoft Tooling e caminhos padrão. Foi testado no vs2019 / netcore3.1.

Substitua "AppDbContext.tt" pelo caminho do arquivo relativo ao projeto:

"$(MSBuildBinPath)\msbuild" $(SolutionPath) /t:$(ProjectName):Transform /p:TransformFile="AppDbContext.tt" /p:CustomAfterMicrosoftCommonTargets="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets"

A Microsoft também possui um guia para disponibilizar macros como "$ (SolutionDirectory)" no modelo usando T4ParameterValues no arquivo do projeto.

npjohns
fonte