web-dev-qa-db-fra.com

Demander à Visual Studio d’exécuter un modèle T4 sur chaque version

Comment puis-je obtenir un modèle T4 pour générer sa sortie sur chaque génération? Dans l’état actuel, il ne le régénère que lorsque je modifie le modèle.

J'ai trouvé d'autres questions similaires à ceci:

transformation T4 et ordre de construction dans Visual Studio (sans réponse)

Comment obtenir des fichiers t4 à construire dans Visual Studio? (les réponses ne sont pas assez détaillées [tout en étant très compliquées] et n'ont même pas de sens total)

Il doit y avoir un moyen plus simple de faire cela!

158
JoelFan

J'ai utilisé la réponse de JoelFan pour venir avec cela. J'aime mieux cela parce que vous n'avez pas à vous souvenir de modifier l'événement de pré-génération chaque fois que vous ajoutez un nouveau fichier .tt au projet.

  • ajoutez TextTransform.exe à votre %PATH%
  • créé un fichier batch nommé transform_all.bat (voir ci-dessous)
  • créer un événement de pré-construction "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
68
Seth Reno

Je suis d'accord avec GarethJ - dans VS2010, il est beaucoup plus facile de régénérer des modèles tt sur chaque build. Le blog d'Oleg Sych explique comment procéder. En bref:

  1. Installer Visual Studio SDK
  2. Installer Kit de développement logiciel de visualisation et de modélisation Visual Studio 201
  3. Ouvrir dans le fichier de projet de l'éditeur de texte et ajouter à la fin du fichier, mais avant </Project>

C'est ça. Ouvrez votre projet. Sur chaque construction, tous les modèles * .tt seront retraités

<!-- 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" />
69
Cheburek

Il y a un excellent paquet NuGet qui fait justement ceci:

PM> Install-Package Clarius.TransformOnBuild

Les détails sur le paquet peuvent être trouvé ici

29
GavKilbride

J'ai utilisé la réponse de MarkGr et développé cette solution. Commencez par créer un fichier batch appelé RunTemplate.bat dans un dossier séparé tools au-dessus du dossier principal de la solution. Le fichier de commandes n'a que la ligne:

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

Ce fichier de commandes prend 2 paramètres ... % 1 est le chemin d'accès au fichier .tt sans l'extension .tt. % 2 est le chemin d'accès à toutes les DLL référencées par les directives Assembly dans le modèle.

Ensuite, allez dans les Propriétés du projet du projet contenant le modèle T4. Allez dans Build Events et ajoutez ce qui suit Ligne de commande de l'événement de pré-construction:

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

remplacer MyTemplate par le nom de fichier de votre fichier .tt (c'est-à-dire MyTemplate.tt) sans l'extension .tt. Cela aura pour résultat d'élargir le modèle pour produire MyTemplate.cs avant de générer le projet. Ensuite, la version actuelle compilera MyTemplate.cs.

20
JoelFan

Récemment trouvé ce super plug-in VS, Chirpy .

Non seulement il génère votre T4 sur une version, mais il permet une approche basée sur T4 de la minification de javascript, CSS et vous permet même d'utiliser la syntaxe LESS pour votre CSS!

14
Mark Melville

Le moyen le plus simple consiste probablement à installer une extension Visual Studio appelée AutoT4 .

Il exécute tous les modèles T4 sur construire automatiquement.

13
Saul

La pré-construction peut être réduite à une seule ligne:

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

Ceci transforme tous les .tt fichiers du projet et les répertorie dans la sortie de la construction.

Si vous ne voulez pas la sortie de la compilation, alors vous devez contourner certains "comportement intéressant" :

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

Bien sûr, vous pouvez extraire cela dans un fichier de commandes auquel vous transmettez le chemin du répertoire du projet si vous le souhaitez.

[~ # ~] nb [~ # ~] Le chemin peut nécessiter quelques ajustements. Le chemin ci-dessus est celui où VS 2008 l’a installé sur ma machine; mais vous pouvez trouver que le numéro de version compris entre TextTemplating et TextTransform.exe est différent.

12
Peter Taylor

Consultez C:\Program Files (x86)\Common Files\Microsoft Shared\TextTemplating. Il existe un fichier EXE de transformation de ligne de commande. Vous pouvez également écrire une tâche MSBuild avec un hôte personnalisé et effectuer la transformation vous-même.

9
MarkGr

En développant les réponses Seth Reno et JoelFan , je suis venu avec cela. Avec cette solution, vous n'avez pas besoin de vous souvenir de modifier l'événement de pré-génération chaque fois que vous ajoutez un nouveau fichier .tt au projet.

Procédure de mise en œuvre

  • Créez un fichier batch nommé transform_all.bat (voir ci-dessous)
  • Créez un événement de pré-génération transform_all.bat "$(ProjectDir)" $(ProjectExt) pour chaque projet avec le fichier .tt que vous souhaitez générer.

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 transformation de texte suppose que le code du modèle T4 est la même langue que votre type de projet. Si ce cas ne vous concerne pas, vous devrez remplacer l'argument $(ProjectExt) par l'extension des fichiers que vous souhaitez générer.

  2. Les fichiers .TT Doivent être dans le répertoire du projet sinon ils ne seront pas construits. Vous pouvez créer des fichiers TT en dehors du répertoire du projet en spécifiant un chemin différent comme premier argument (), c’est-à-dire remplacez "$(ProjectDir)" avec le chemin contenant les fichiers TT.)

  3. Pensez également à définir le chemin correct vers le fichier de commandes transform_all.bat.
    Par exemple, je l'ai placé dans mon répertoire de solution afin que l'événement de pré-génération se présente comme suit "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

7
Alex Essilfie

Si vous utilisez Visual Studio 2010, vous pouvez utiliser le Kit de développement logiciel de visualisation et de modélisation Visual Studio: http://code.msdn.Microsoft.com/vsvmsdk

Ceci contient les tâches msbuild pour l'exécution des modèles T4 au moment de la construction.

Consultez le blog d'Oleg pour plus d'explications: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration

6
GarethJ

Hé, mon script peut aussi analyser l'extension de sortie

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%

Créez simplement l'événement transform_all.bat $(SolutionDir) pre-build, et tous les fichiers * .tt de votre solution seront transformés automatiquement.

4
MadRabbit

Dynamo.AutoTT fera ce dont vous avez besoin. Vous pouvez le configurer pour regarder des fichiers via une regex ou générer lors de la construction. Il vous permet également de spécifier les modèles T4 que vous souhaitez déclencher.

Vous pouvez le télécharger ici: https://github.com/MartinF/Dynamo.AutoTT

Il suffit de le construire, de copier les fichiers dll et AddIn dans

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

et vous partez.

Si vous souhaitez le lancer dans VS2012, vous devez modifier le fichier Dynamo.AutoTT.AddIn et définir la version sur 11.0 dans le fichier AddIn.

3
Matware

Un autre bon article à ce sujet: Génération de code dans un processus de construction

Lien de téléchargement du SDK de modélisation et de visualisation 2012:

https://www.Microsoft.com/en-us/download/details.aspx?id=3068

2
lvanzyl

Voir la réponse de mhutch https://stackoverflow.com/a/1395377/9587

IMHO, c'est le meilleur serveur de construction et l'option favorable à l'environnement de développement.

2
Ethan J. Brown

Il vous suffit d'ajouter cette commande à l'événement de pré-génération du projet:

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

La vérification de la configuration = debug, assure que vous ne régénérez pas le code en mode édition, lorsque vous effectuez la compilation sur le serveur de génération TFS, par exemple.

1
anoop

Dans Visual Studio 2013, cliquez avec le bouton droit sur le modèle T4 et définissez la propriété de transformation lors de la génération sur true.

1
user1607685

Voici ma solution - semblable à la réponse acceptée. Nous avons eu un problème avec notre contrôle de source. Les fichiers .cs cibles sont en lecture seule et le T4 échouait. Voici le code qui exécute T4 dans le dossier temporaire, compare les fichiers cible et ne le copie que si les mêmes modifications étaient apportées. Cela ne résout pas le problème des fichiers read.only, mais au moins cela ne se produit pas très souvent:

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

Vous pouvez essayer d’ajouter votre commande d’extraction sur une ligne (:: Vous pouvez essayer ....)

Dans votre projet, définissez ceci comme une action de pré-construction:

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

T4Executer le fait pour VS2019. Vous pouvez spécifier les modèles à ignorer lors de la construction, et il existe une option d'exécution après génération.

1
Epsilekt

Voici comment je l'ai cloué. Lien . Construire essentiellement sur un blog de qualité (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ ne peut pas publier plus que 2 links :() J'ai créé ce fichier . cibles à utiliser avec les fichiers Visual Studio Proj.

C'est utile lorsque vous utilisez d'autres dll-s à l'intérieur de votre .tt et que vous voulez que le résultat change au fur et à mesure que les dll-s changent.

Comment ça marche:

  1. Créez le tt, ajoutez le nom d'assembly = "$ (SolutionDir) path\to\other\project\output\foo.dll et configurez la transformation et le résultat de la manière attendue
  2. Supprimer les références d'assemblage de .tt

  3. Dans le fichier proj, utilisez ce code pour configurer la transformation lors de la construction:

    <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>
    
    • Première partie Localise TextTransform.exe

    • $(IncludeForTransform) sera égal à c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll car c'est le moyen d'ajouter des références pour TextTransform sur la ligne de commande

       <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" /> cela crée une liste de tous les fichiers tt du projet et des sous-répertoires

    • <Exec Command="... Produit une ligne ressemblant à "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll" Pour chacun des fichiers .tt trouvés.

  4. La seule chose à faire est d'ajouter les chemins aux dll à l'intérieur 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>
    

    Ici <InProject>False</InProject> Masque ces éléments de la vue Solution

Alors maintenant, vous devriez être capable de générer votre code sur la construction et sur le changement de dll-s.

Vous pouvez supprimer l'outil personnalisé (des propriétés à l'intérieur de Visual Studio) afin que le système virtuel n'essaye pas de se transformer et échoue lamentablement à chaque fois. Parce que nous avons supprimé les références d'assemblage à l'étape 2

1
Georgi

Vous venez d'installer le package NuGet: Clarius.TransformOnBuild

Ensuite, chaque fois que vous cliquez sur reconstruction projet (ou solution), vos fichiers . Tt seront exécutés.

0
dqthe

Dans Visual Studio 2017 (probablement aussi dans les prochaines versions), vous devez ajouter ceci dans l'événement Pre-build:

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

p.s. Modifiez le chemin d'accès à votre modèle s'il ne se trouve pas dans le répertoire du projet racine.

0
random one

n type construit un paquet nuget pour cela.

Note latérale: Je reçois des erreurs de compilation de TextTemplate.exe et de ce package (car ce package appelle TextTemplate.exe), mais pas de Visual Studio. Donc, apparemment, le comportement n'est pas le même. la tête haute.

EDIT: This a fini par être mon problème.

0
Grault