Consigue que Visual Studio ejecute una plantilla T4 en cada compilación


¿Cómo puedo obtener una plantilla T4 para generar su salida en cada compilación? Como está ahora, solo lo regenera cuando hago un cambio en la plantilla.

He encontrado otras preguntas similares a esta:

Transformación de T4 y orden de compilación en Visual Studio (sin respuesta)

¿Cómo obtener archivos t4 para construir en visual studio? (las respuestas no son lo suficientemente detalladas [aunque siguen siendo bastante complicadas] y ni siquiera tienen sentido total)

Tiene que haber un una forma más sencilla de hacer esto!

Author: abatishchev, 2009-10-30

19 answers

Usé la respuesta de JoelFan para aparecer con esto. Me gusta más porque no tienes que recordar modificar el evento pre-build cada vez que añadas un nuevo archivo .tt al proyecto.

  • añadir TextTransform.exe a su %PATH%
  • creó un archivo por lotes llamado transform_all.mtd (véase infra)
  • crear un evento de pre-compilación"transform_all ..\.."

Transform_all.mtd

@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
 65
Author: Seth Reno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-11 17:22:19

Estoy de acuerdo con GarethJ - en VS2010 es mucho más fácil regenerar plantillas tt en cada compilación. El blog de Oleg Sych describe cómo hacerlo. En resumen:

  1. Instalar Visual Studio SDK
  2. Instalar Modelado de Visual Studio 2010 y Visualización SDK
  3. Abrir en el archivo de proyecto del editor de texto y añadir al final del fichero pero antes de </Project>

Eso es todo. Abre tu proyecto. En cada compilación todas las plantillas *.tt serán reprocesadas

<!-- 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" />
 66
Author: Cheburek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-01 11:09:50

Hay un gran paquete NuGet que hace precisamente esto:

PM> Install-Package Clarius.TransformOnBuild

Los detalles sobre el paquete pueden encontrarse aquí

 24
Author: GavKilbride,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-17 23:19:13

Usé la respuesta de MarkGr y desarrollé esta solución. Primero, cree un archivo por lotes llamado RunTemplate.bat en una carpeta separada tools encima de la carpeta principal solution. El archivo por lotes solo tiene la línea:

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

Este archivo por lotes toma 2 parámetros... %1 es la ruta de acceso .tt archivo sin el .tt extensión. %2 es la ruta a cualquier DLL a la que se refieran las directivas Assembly en la plantilla.

A continuación, vaya a las propiedades del proyecto de el proyecto que contiene la plantilla T4. Vaya a Build Events y agregue el siguiente Pre-build event command line :

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

Reemplazando Miplantilla con el nombre de su .tt archivo (es decir, Miplantilla.tt) sin el .tt extensión. Esto tendrá el resultado de expandir la plantilla para producir MyTemplate.cs antes de construir el proyecto. A continuación, la construcción actual se compilará Miplantilla.cs

 19
Author: JoelFan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-03 20:05:24

Recientemente encontrado este gran complemento VS, Chirpy.

No solo genera tu T4 en una compilación, sino que permite un enfoque basado en T4 para la minificación de javascript, CSS e incluso te permite usar MENOS sintaxis para tu CSS.

 14
Author: Mark Melville,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-07 01:54:00

La pre-construcción se puede reducir a una sola línea:

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

Esto transforma todos los archivos .tt en el proyecto y los enumera en la salida de compilación.

Si no quieres la salida de compilación, entonces tienes que trabajar alrededor de algún "comportamiento interesante":

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

Por supuesto, puede extraer esto en un archivo por lotes al que pase la ruta del directorio del proyecto si lo desea.

NB La ruta puede requerir algunos ajustes. El camino de arriba es donde VS 2008 instalado en mi máquina, pero usted puede encontrar que el número de versión entre TextTemplating y TextTransform.exe es diferente.

 11
Author: Peter Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:20

Probablemente la forma más sencilla es instalar una extensión de Visual Studio llamada AutoT4.

Ejecuta todas las plantillas T4 en la compilación automáticamente.

 11
Author: Saul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-16 13:52:07

Echa un vistazo C:\Program Files(x86) \ Common Files \ Microsoft Shared\TextTemplating hay un exe de transformación de línea de comandos allí. Alternativamente, escriba una tarea de MSBuild con un host personalizado y haga la transformación usted mismo.

 9
Author: MarkGr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-02 00:43:22

AmpliandoSeth Reno ylas respuestas de JoelFan , se me ocurrió esto. Con esta solución no necesita recordar modificar el evento de pre-compilación cada vez que agregue un nuevo archivo .tt al proyecto.

Procedimiento de ejecución

  • Cree un archivo por lotes llamado transform_all.mtd (véase infra)
  • Crear un evento pre-build transform_all.bat "$(ProjectDir)" $(ProjectExt) para cada proyecto .tt desea build

Transform_all.mtd

@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. La transformación de texto asume que el código de la plantilla T4 es el mismo idioma que el tipo de proyecto. Si este caso no se aplica a usted, entonces tendrá que reemplazar el argumento $(ProjectExt) con la extensión de los archivos que desea que genere el código.

  2. .TT los archivos deben estar en el directorio del proyecto, de lo contrario no se compilarán. Puede construir archivos TT fuera de la project directory especificando una ruta diferente como primer argumento ( es decir, reemplace "$(ProjectDir)" con la ruta que contiene los archivos TT.)

  3. Recuerde también establecer la ruta correcta al archivo por lotes transform_all.bat.
    Por ejemplo, lo coloqué en el directorio de mi solución para que el evento pre-build fuera el siguiente "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

 7
Author: Alex Essilfie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:43

Si está utilizando Visual Studio 2010, puede utilizar el SDK de Modelado y visualización de Visual Studio: http://code.msdn.microsoft.com/vsvmsdk

Esto contiene tareas de msbuild para ejecutar plantillas T4 en tiempo de compilación.

Echa un vistazo al blog de Oleg para más explicaciones: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration

 6
Author: GarethJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 23:39:31

Hey, mi script también puede analizar la extensión de salida

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%

Simplemente cree transform_all.bat $(SolutionDir) evento de pre-compilación, y todos los archivos *.tt en su solución se transformarán automáticamente.

 4
Author: MadRabbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-25 15:26:49

Dinamo.AutoTT hará lo que necesites. Puede configurarlo para ver archivos a través de una expresión regular o generar en la compilación. También le permite especificar qué plantillas de T4 desea que active.

Puedes descargarlo desde aquí: https://github.com/MartinF/Dynamo.AutoTT

Simplemente compílelo, copie los archivos dll y AddIn en

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

Y allá vas.

Si desea ponerlo en marcha en VS2012, deberá modificar la Dinamo A.Autott.Archivo AddIn y establecer la versión a 11.0 dentro del archivo AddIn;

 3
Author: Matware,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-03 00:11:16

Otro buen artículo sobre esto: Generación de código en un Proceso de Compilación

2012 Modelado y Visualización SDK enlace de descarga:

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

 2
Author: lvanzyl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-22 22:28:23

Por favor, consulte la respuesta de mhutch https://stackoverflow.com/a/1395377/9587

En mi humilde opinión, esta es la mejor opción de servidor de compilación y desarrollo amigable con el medio ambiente.

 2
Author: Ethan J. Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-19 20:06:34

Aquí está mi solución - similar a la respuesta aceptada. Tuvimos un problema con nuestro control de fuentes. Objetivo .los archivos CS son de solo lectura y el T4 estaba fallando. Aquí está el código, que ejecuta T4 en la carpeta temp, compara los archivos de destino y lo copia solo en caso del mismo cambio. No soluciona el problema con read.solo archivos, pero al menos no ocurre muy a menudo:

Transformar.mtd

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

Puedes intentar añadir tu comando de check-out en una línea (:: Puedes intentarlo ....)

En tu proyecto establece esto como una acción prediseñada:

Path-To-Transform.bat "$(ProjectDir)"
 1
Author: Ondra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-20 14:23:51

Solo necesita agregar este comando al evento pre-build del proyecto:

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

El check on configuration = debug, se asegura de que no se regenere el código en el modo release, cuando se hace la compilación en el servidor de compilación de TFS, por ejemplo.

 1
Author: anoop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-28 16:25:00

En visual studio 2013, haga clic con el botón derecho en la plantilla T4 y establezca la propiedad transform on build en true.

 1
Author: user1607685,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-29 12:42:16

Un tipo construyó un paquete nuget para esto.

Nota al margen: Obtengo errores de compilación de ambos TextTemplate.exe y ese paquete (porque ese paquete llama a TextTemplate.exe) pero no desde Visual Studio. Así que aparentemente el comportamiento no es el mismo; heads up.

EDITAR: Esto terminó siendo mi problema.

 0
Author: Grault,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:20

Así es como lo viré. Enlace . Básicamente construyendo sobre un gran blog( blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ can't post more that 2 links: () Se me ocurrió esto .archivos de destino para usar con archivos proj de visual studio.

Es útil cuando está utilizando otras dll-s dentro de su .tt y desea que el resultado cambie a medida que las dll-s están cambiando.

Cómo obras:

  1. Cree el tt, agregue el nombre del ensamblado="path(SolutionDir)path\to\other\project\output\foo.dll y configurar la transformación y el resultado para ser como se esperaba
  2. Eliminar las referencias de montaje de .tt

  3. Dentro del archivo proj use este código para configurar 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 primera parte Localiza TextTransform.exe

    • $(IncludeForTransform) será igual a c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll porque esa es la forma de agregar referencias para el TextTransform en la línea de comandos

       <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" />esto crea una lista de todos los archivos tt dentro del proyecto y subdirectorios

    • <Exec Command="... produce una línea para cada uno de los archivos .tt encontrados que se ve como "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. Lo único que queda por hacer es agregar las rutas a las DLL 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>
    

    Aquí <InProject>False</InProject> oculta estos elementos de la Vista de solución

Así que ahora usted debe ser capaz de genere su código en la compilación y en el cambio de dll-s.

Puede eliminar la herramienta personalizada (de las propiedades dentro de Visual Studio) para que el VS no intente transformarse y falle miserablemente cada vez. Porque eliminamos las referencias de ensamblado en el paso 2

 0
Author: Georgi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-23 18:03:50