Pregunta

¿Cómo puedo obtener una T4 plantilla para generar su salida en cada generación?Como lo es ahora, sólo se regenera cuando hago un cambio en la plantilla.

He encontrado otra pregunta similar a esta:

T4 de transformación y orden de generación en Visual Studio (sin respuesta)

Cómo llegar a la t4 la acumulación de archivos en visual studio? (las respuestas no son lo suficientemente detalladas, [mientras que todavía siendo bastante complicado] y ni siquiera sentido total)

Tiene que haber una manera más simple de hacer esto!

¿Fue útil?

Solución

Usé la respuesta de JoelFan para aparecer con esto. Me gusta más porque no tiene que recordar modificar el evento previo a la compilación cada vez que agrega un nuevo archivo .tt al proyecto.

  • agregue TextTransform.exe a su %PATH%
  • creó un archivo por lotes llamado transform_all.bat (ver más abajo)
  • crear un evento previo a la compilación " 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

Otros consejos

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 Visual Modelado de Studio 2010 y SDK de visualización
  3. Abrir en el archivo de proyecto del editor de texto y agregar al final del archivo 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" />

Hay un gran paquete NuGet que hace exactamente esto:

PM> Install-Package Clarius.TransformOnBuild

Los detalles sobre el paquete pueden ser encontrado aquí

Utilicé la respuesta de MarkGr y desarrollé esta solución. Primero, cree un archivo por lotes llamado RunTemplate.bat en una carpeta separada de herramientas sobre la carpeta principal de la solución. 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 al archivo .tt sin la extensión .tt. % 2 es la ruta a las DLL a las que se refieren las directivas Assembly en la plantilla.

A continuación, vaya a las Propiedades del proyecto del proyecto que contiene la plantilla T4. Vaya a Crear eventos y agregue la siguiente línea de comando de evento previo a la compilación :

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

reemplazando MyTemplate con el nombre de archivo de su archivo .tt (es decir, MyTemplate.tt) sin la extensión .tt. Esto tendrá el resultado de expandir la plantilla para producir MyTemplate.cs antes de construir el proyecto. Entonces la compilación real compilará MyTemplate.cs

Recientemente encontré este excelente 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!

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

Ejecuta todas las plantillas T4 en la compilación de forma automática.

El pre-build puede ser reducido 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 a todos .tt los archivos en el proyecto y listas de ellos a la salida de la compilación.

Si usted no desea que la salida de la compilación, a continuación, usted tiene que trabajar en torno a algunos "un comportamiento interesante":

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

Por supuesto, usted puede tirar de esto en un archivo por lotes para que se pasa el proyecto de la ruta de acceso del directorio, si lo desea.

NB La ruta de acceso 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.

Echa un vistazo C: \ Archivos de programa (x86) \ Archivos comunes \ Microsoft Shared \ TextTemplating hay una transformación de línea de comando exe allí. Alternativamente, escriba una tarea de MSBuild con un host personalizado y realice la transformación usted mismo.

Expandiendo en Seth Reno y Las respuestas de JoelFan , se me ocurrió esto. Con esta solución, no necesita recordar modificar el evento previo a la compilación cada vez que agrega un nuevo archivo .tt al proyecto.

Procedimiento de implementación

  • Cree un archivo por lotes denominado transform_all.bat (ver más abajo)
  • Cree un evento previo a la compilación transform_all.bat "$(ProjectDir)" $(ProjectExt) para cada proyecto con un .tt que desee compilar

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

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

  4. Recuerde también configurar la ruta correcta al archivo por lotes transform_all.bat.
    Por ejemplo, lo coloqué en mi directorio de soluciones para que el evento previo a la compilación fuera el siguiente "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

Si está utilizando Visual Studio 2010, puede usar el SDK de visualización y modelado 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 obtener más explicaciones: http://www.olegsych.com/2010/04/understanding-t4 -msbuild -integration

Hola, 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 previo a la compilación, y todos los archivos * .tt en su solución se transformarán automáticamente.

Dynamo.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 T4 desea que active.

Puede 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 ya está.

Si desea que funcione en VS2012, deberá modificar el archivo Dynamo.AutoTT.AddIn y establecer la Versión en 11.0 dentro del archivo AddIn;

Aquí está mi solución, similar a la respuesta aceptada. Tuvimos un problema con nuestro control de fuente. Los archivos .cs de destino son de solo lectura y el T4 estaba fallando. Aquí está el código, que ejecuta T4 en la carpeta temporal, compara los archivos de destino y los copia solo en caso de que se produzca el mismo cambio. No soluciona el problema con los archivos read.only, pero al menos no ocurre con mucha frecuencia:

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

Puede intentar agregar su comando de check-out en una línea (:: Puede intentar ....)

En su proyecto, establezca esto como una acción previa a la creación:

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

Solo necesita agregar este comando al evento previo a la compilación del proyecto:

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

La comprobación de configuration = debug, asegura que no regeneres el código en el modo de lanzamiento, cuando haces la compilación en el servidor de compilación TFS, por ejemplo.

En Visual Studio 2013, haga clic con el botón derecho en la plantilla T4 y establezca la transformación en la propiedad de compilación en verdadero.

Así es como lo vi. 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/ no puede publicar más de 2 enlaces :() Se me ocurrió este .targets para usar con archivos de estudio visual studio.

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

Cómo funciona:

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

  3. Dentro del archivo de proyecto, use este código para configurar la transformación en la compilación:

    <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 TextTransform en la línea 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" /> 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 parece 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. Lo único que queda por hacer es agregar las rutas a los 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>
    

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

Entonces, ahora debería poder generar 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 ensamblaje en el paso 2

T4Executer hace esto para VS2019. Puede especificar plantillas para ignorar en la compilación, y hay una opción de ejecución después de la compilación.

Algún tipo creó un paquete nuget para esto.

Nota al margen: Recibo errores de compilación tanto de TextTemplate.exe como de ese paquete (porque ese paquete llama a TextTemplate.exe) pero no de Visual Studio. Entonces aparentemente el comportamiento no es el mismo; cabezas arriba.

EDITAR: Esto terminó siendo mi problema.

Simplemente instala el paquete NuGet: Clarius.TransformOnBuild

Luego, cada vez que haga clic en Reconstruir proyecto (o Solución), sus archivos .tt se ejecutarán

En Visual Studio 2017 (probablemente también en las próximas versiones), debe agregar esto en el evento Pre-build:

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

p.s. Cambie la ruta a su plantilla si no se encuentra en el directorio raíz del proyecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top