Domanda

Come posso ottenere un modello T4 per generare il suo output su ogni build? Come è ora, lo rigenera solo quando apporto una modifica al modello.

Ho trovato altre domande simili a questa:

Trasformazione T4 e ordine di compilazione in Visual Studio ( senza risposta)

Come ottenere file t4 da compilare visivamente studio? (le risposte non sono abbastanza dettagliate [pur essendo ancora molto complicate] e non hanno nemmeno un senso totale)

Deve esserci un modo più semplice per farlo!

È stato utile?

Soluzione

Ho usato la risposta di JoelFan per trovare questo. Mi piace di più perché non devi ricordare di modificare l'evento pre-build ogni volta che aggiungi un nuovo file .tt al progetto.

  • aggiungi TextTransform.exe al tuo %PATH%
  • ha creato un file batch chiamato transform_all.bat (vedi sotto)
  • crea un evento pre-build " 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

Altri suggerimenti

Sono d'accordo con GarethJ - in VS2010 è molto più facile rigenerare i template tt su ogni build. Il blog di Oleg Sych descrive come farlo. In breve:

  1. Installa Visual Studio SDK
  2. Installa Visual Modellazione di Studio 2010 e SDK di visualizzazione
  3. Apri nel file di progetto dell'editor di testo e aggiungi alla fine del file ma prima di </Project>

Questo è tutto. Apri il tuo progetto. Su ogni build verranno rielaborati tutti i modelli * .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" />

Esiste un ottimo pacchetto NuGet che fa proprio questo:

PM> Install-Package Clarius.TransformOnBuild

I dettagli sul pacchetto possono essere trovato qui

Ho usato la risposta di MarkGr e ho sviluppato questa soluzione. Innanzitutto, crea un file batch chiamato RunTemplate.bat in una cartella strumenti separata sopra la cartella principale della soluzione. Il file batch ha solo la riga:

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

Questo file batch accetta 2 parametri ... % 1 è il percorso del file .tt senza estensione .tt. % 2 è il percorso di qualsiasi DLL a cui fanno riferimento le direttive Assembly nel modello.

Successivamente, vai nelle proprietà del progetto del progetto contenente il modello T4. Accedi a Crea eventi e aggiungi la seguente riga di comando dell'evento pre-build :

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

sostituendo MyTemplate con il nome del tuo file .tt (ovvero MyTemplate.tt) senza l'estensione .tt. Ciò avrà il risultato di espandere il modello per produrre MyTemplate.cs prima di creare il progetto. Quindi la build effettiva compilerà MyTemplate.cs

Recentemente ho trovato questo fantastico plugin VS, Chirpy .

Non solo genera il tuo T4 su una build, ma consente un approccio basato su T4 alla minimizzazione di javascript, CSS e ti consente persino di usare MENO sintassi per il tuo CSS!

Probabilmente il modo più semplice è installare un'estensione di Visual Studio chiamata AutoT4 .

Esegue tutti i modelli T4 su build automagicamente.

La pre-build può essere ridotta a una sola riga:

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

Questo trasforma tutti i .tt file nel progetto e li elenca nell'output di compilazione.

Se non si desidera l'output di compilazione, è necessario aggirare alcuni " comportamento interessante " :

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

Naturalmente, puoi estrarlo in un file batch a cui passi il percorso della directory del progetto, se lo desideri.

NB Il percorso potrebbe richiedere alcune modifiche. Il percorso sopra è dove VS 2008 lo ha installato sulla mia macchina; ma potresti scoprire che il numero di versione compreso tra TextTemplating e TextTransform.exe è diverso.

Guarda C: \ Programmi (x86) \ File comuni \ Microsoft Shared \ TextTemplating c'è un exe di trasformazione della riga di comando in là. In alternativa, scrivi un'attività MSBuild con un host personalizzato e fai tu stesso la trasformazione.

Espansione su Seth Reno e Le risposte di JoelFan , mi sono inventato questo. Con questa soluzione non è necessario ricordare di modificare l'evento pre-build ogni volta che si aggiunge un nuovo file .tt al progetto.

Procedura di attuazione

  • Crea un file batch chiamato transform_all.bat (vedi sotto)
  • Crea un evento pre-build transform_all.bat "$(ProjectDir)" $(ProjectExt) per ogni progetto con un .tt che vuoi creare

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


NOTE

  1. La trasformazione del testo presuppone che il codice nel modello T4 abbia la stessa lingua del tipo di progetto. Se questo caso non ti riguarda, dovrai sostituire l'argomento $(ProjectExt) con l'estensione dei file che desideri generare il codice.

  2. I file
  3. .TT devono trovarsi nella directory del progetto, altrimenti non verranno creati. Puoi creare file TT all'esterno della directory del progetto specificando un percorso diverso come primo argomento ( vale a dire sostituisci "$(ProjectDir)" con il percorso contenente i file TT.)

  4. Ricorda anche di impostare il percorso corretto per il file batch transform_all.bat.
    Ad esempio, l'ho inserito nella mia directory della soluzione in modo che l'evento pre-build fosse il seguente "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

Se si utilizza Visual Studio 2010, è possibile utilizzare Visual Studio Modeling and Visualization SDK: http://code.msdn.microsoft.com/vsvmsdk

Questo contiene compiti di msbuild per l'esecuzione di modelli T4 in fase di compilazione.

Dai un'occhiata al blog di Oleg per ulteriori spiegazioni: http://www.olegsych.com/2010/04/understanding-t4 -msbuild integrazione

Hey, il mio script può anche analizzare l'estensione di output

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 creare transform_all.bat $(SolutionDir) evento pre-build e tutti i file * .tt nella soluzione verranno trasformati automaticamente.

Dynamo.AutoTT farà ciò di cui hai bisogno. È possibile configurarlo per guardare i file tramite un regex o generare su build. Consente inoltre di specificare quali modelli T4 si desidera attivare.

Puoi scaricarlo da qui: https://github.com/MartinF/Dynamo.AutoTT

Basta crearlo, copiare i file dll e AddIn in

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

e via.

Se vuoi farlo funzionare in VS2012 dovrai modificare un file Dynamo.AutoTT.AddIn e impostare la versione su 11.0 all'interno del file AddIn;

Ecco la mia soluzione, simile alla risposta accettata. Abbiamo avuto un problema con il nostro controllo del codice sorgente. I file .cs di destinazione sono di sola lettura e il T4 non funzionava. Ecco il codice, che esegue T4 nella cartella temporanea, confronta i file di destinazione e lo copia solo in caso di stessa modifica. Non risolve il problema con i file read.only, ma almeno non si verifica molto spesso:

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

Puoi provare ad aggiungere il tuo comando di check-out su una riga (:: Puoi provare ....)

Nel progetto, impostalo come azione pre-compilata:

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

Devi solo aggiungere questo comando all'evento pre-build del progetto:

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

Il controllo su configuration = debug, assicura che non si rigeneri il codice nella modalità di rilascio, ad esempio quando si esegue la build sul server di build TFS.

In Visual Studio 2013, fai clic con il pulsante destro del mouse sul modello T4 e imposta la proprietà transform on build su true.

Ecco come l'ho affrontato. Link . Fondamentalmente basandosi su un grande blog (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ non posso pubblicare più di 2 links :() Ho ideato questo .targets per l'uso con file proj di Visual Studio.

È utile quando stai usando altre DLL all'interno del tuo .tt e vuoi che il risultato cambi mentre le DLL stanno cambiando.

Come funziona:

  1. Crea tt, aggiungi il nome dell'assembly = " $ (SolutionDir) percorso \ a \ other \ project \ output \ foo.dll e imposta la trasformazione e il risultato come previsto
  2. Rimuovi i riferimenti di assieme da .tt

  3. All'interno del file proj usa questo codice per impostare transform on build:

    <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>
    
    • La prima parte individua TextTransform.exe

    • $(IncludeForTransform) sarà uguale a c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll perché questo è il modo di aggiungere riferimenti per TextTransform sulla riga di 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" /> questo crea un elenco di tutti i file tt all'interno del progetto e delle sottodirectory

    • <Exec Command="... produce una linea per ciascuno dei file .tt trovati che assomiglia a "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. L'unica cosa che resta da fare è aggiungere i percorsi alle dll all'interno di:

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

    Qui <InProject>False</InProject> nasconde questi elementi dalla Vista soluzione

Quindi ora dovresti essere in grado di generare il tuo codice su build e su change di dll-s.

È possibile rimuovere lo strumento personalizzato (dalle proprietà all'interno di Visual Studio) in modo che VS non cerchi di trasformare e fallire miseramente ogni volta. Perché abbiamo rimosso i riferimenti dell'assembly nel passaggio 2

T4Executer lo fa per VS2019. Puoi specificare i modelli da ignorare durante la compilazione e c'è un'opzione di esecuzione dopo la compilazione.

Qualcuno ha realizzato un pacchetto nuget per questo.

Nota a margine: ottengo errori di compilazione sia da TextTemplate.exe che da quel pacchetto (perché quel pacchetto chiama TextTemplate.exe) ma non da Visual Studio. Quindi apparentemente il comportamento non è lo stesso; in testa.

EDIT: Questo ha finito per essere il mio problema.

Devi solo installare il pacchetto NuGet: Clarius.TransformOnBuild

Quindi, ogni volta che fai clic su Ricostruisci progetto (o soluzione), i tuoi file .tt verranno eseguiti

In Visual Studio 2017 (probabilmente anche le versioni successive), dovresti aggiungerlo nell'evento Pre-build:

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

P.S. Cambia il percorso del tuo modello se non si trova nella directory principale del progetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top