Obtenga Visual Studio para ejecutar una plantilla T4 en cada compilación

163

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

He encontrado otras preguntas similares a esta:

Transformación 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)

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

JoelFan
fuente
Si bien personalmente estaría bastante interesado en escuchar una respuesta a esto, ¿cuál es su escenario particular? Normalmente, la salida de la plantilla debe ser función de la entrada solamente, por lo que generar cambios está bien.
Pavel Minaev
66
Mi plantilla utiliza la reflexión para examinar otros ensamblajes, que pueden haber cambiado desde la última compilación.
JoelFan
¿Qué pasa con esta idea: stackoverflow.com/questions/1649649/…
JoelFan
Mi plantilla tiene un propósito, registrar la hora de la fecha de compilación.
Scott Solmer

Respuestas:

68

Usé la respuesta de JoelFan para aparecer con esto. Me gusta más porque no tiene que acordarse de 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
Seth Reno
fuente
28
Buena solución Preferí poner la ruta completa a TextTransform.exe ( "%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe") en el archivo por lotes, en lugar de agregarlo a% PATH%
Adam Nofsinger
20
Una variable mejor sería% COMMONPROGRAMFILES (x86)% en lugar de% COMMONPROGRAMFILES%, ya que también funcionaría en un sistema de 64 bits.
Durden81
3
Así será el camino completo %COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe. Envuélvelo entre comillas dobles.
northben
1
@ piers7: Actualicé el código para detectar automáticamente la 'bitness' del sistema operativo que ejecuta el script. También he incluido el comentario de northben para omitir el directorio obj e implementado la preferencia de Adam Nofsinger para no modificar la variable de entorno% PATH%.
Alex Essilfie
1
En mi humilde opinión tener que proporcionar el camino a la TextTransform.exemierda. Ya puede hacer clic con el botón derecho en "Ejecutar herramienta personalizada" en Visual Studio, por lo que ya tiene la ruta de la herramienta. ¿Por qué tengo que pasar por el trabajo de proporcionarlo nuevamente cuando construyo desde un contexto de Visual Studio?
Jez
70

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

  1. Instalar SDK de Visual Studio
  2. Instale el SDK de visualización y modelado de Visual Studio 2010
  3. Abrir en el archivo de proyecto del editor de texto y agregar al final del archivo pero antes </Project>

Eso es. 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" />
Cheburek
fuente
2
Aquí hay un enlace a la publicación del blog de Oleg Sych: olegsych.com/2010/04/understanding-t4-msbuild-integration
PhilChuang
44
Esta es una muy buena solución. Sin embargo, ¿hay alguna manera de hacer que esto funcione sin requerir la instalación de los SDK? He estado tratando de hacerlo funcionar copiando los archivos .targets y ensamblajes relacionados, pero sin éxito.
Grimus
3
Parece que Chirpy funciona sin tener que descargar ningún SDK ... sin embargo, aún tiene que descargar y configurar Chirpy. Todavía estoy tratando de descubrir una solución que funcione en una instalación predeterminada de VS2010, y estará disponible a través del repositorio de origen para que los desarrolladores solo necesiten consultar el repositorio para que funcione. Todas estas otras soluciones requieren demasiada atención por desarrollador.
Mir
1
Si crea sus proyectos con la versión x64 de MSBuild, obtendrá este error: 'MSB4019: El proyecto importado "C: \ Archivos de programa (x86) \ MSBuild \ Microsoft \ VisualStudio \ TextTemplating \ v10.0 \ Microsoft.TextTemplating.targets " no fue encontrado.' error. Solución alternativa: reemplace la variable $ (MSBuildExtensionsPath) por $ (MSBuildExtensionsPath32) en un archivo de proyecto.
Oxidado
3
Además, no necesita parchear los archivos .csproj. Desde la línea de comando invocar 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

Hay un gran paquete NuGet que hace exactamente esto:

PM> Install-Package Clarius.TransformOnBuild

Los detalles sobre el paquete se pueden encontrar aquí

GavKilbride
fuente
2
Hay una bifurcación 'no oficial': nuget.org/packages/Clarius.TransformOnBuild-unofficial que admite contentacciones de compilación
Erno
1
Es agradable extensión, pero que se está ejecutando en modo TextTransform.exe la Línea de comando, por lo hostspecific = "true" funcions será no el trabajo
GH61
1
@JenishRabadiya Agregue esta línea en la parte superior de la plantilla:<#@ template language="C#" #>
Peter van Kekem
2
Parece que el paquete se ha actualizado para admitir hostspecific = "true" y otros problemas (hace 8 días)
Mingwei Samuel
1
La acción de compilación de contenido está funcionando ahora con la última versión.
androbin
20

Usé la respuesta de MarkGr y desarrollé esta solución. Primero, cree un archivo por lotes llamado RunTemplate.bat en una carpeta de herramientas separada sobre la carpeta de la solución principal. 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 hacen referencia las directivas de ensamblado en la plantilla.

A continuación, vaya a las Propiedades del proyecto del proyecto que contiene la plantilla T4. Vaya a Eventos de compilación y agregue la siguiente línea de comando de eventos de precompilació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

JoelFan
fuente
aunque todavía tengo el problema: stackoverflow.com/questions/1669893/…
JoelFan el
1
No olvide las comillas alrededor de $ (SolutionDir) .. \ .. \ tools \ RunTemplate.bat
Ewald Hofman
14

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

Mark Melville
fuente
13

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.

Saulo
fuente
¡Convenido! Configurable y funciona con VS 2015. Incluso admite el uso del ensamblaje EnvDTE (para obtener la configuración de compilación), que no todos los métodos lo hacen. El único inconveniente es que todos los miembros del equipo tienen que instalar la extensión.
Gyromite
12

La construcción previa 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 .ttarchivos del proyecto y los enumera en la salida de compilación.

Si no desea el resultado de la compilación, debe evitar algunos "comportamientos interesantes" :

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

Por supuesto, puede extraerlo en un archivo por lotes al que pasará la ruta del directorio del proyecto si lo desea.

Nota : la ruta puede requerir algunos ajustes. La ruta anterior es donde VS 2008 lo instaló en mi máquina; pero es posible que el número de versión entre TextTemplatingy TextTransform.exesea ​​diferente.

Peter Taylor
fuente
@SprintStar, si tiene VS 2012, probablemente haya una mejor manera de hacerlo. Otras respuestas hablan de mejores formas ya existentes para VS 2010.
Peter Taylor
Este es el mejor método, porque no tengo que instalar nada.
Ryan Gates
1
Vi que no había 1.2 pero había un 12.0, así que lo cambié a eso pero obtuve este error:System.Exception: T4MVC can only execute through the Visual Studio host
colmde
1
Solo tenía que actualizar la ruta de la carpeta para usar 14.0 en lugar de 1.2 y listo.
pistola-pete
Esta fue la mejor solución en mi opinión (solo cambiando 14.0 como se mencionó anteriormente)
Nelson Rodriguez
9

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

MarkGr
fuente
1
Ah, aunque puede hacer cosas como "devenv / Command TextTransformation.TransformAllTemplates / Command File.Exit MySolution.sln" en 2010, tiende a romperse ocasionalmente en los servidores de compilación. Su mejor opción es escribir una tarea de MSBuild con un host personalizado.
MarkGr
Para compilaciones de escritorio, solo haga una macro que haga TransformAllTemplates y luego una compilación.
MarkGr el
7

Ampliando las respuestas de Seth Reno y 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 implementacion

  • Cree un archivo por lotes llamado 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 supone 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 $(ProjectExt)argumento con la extensión de los archivos que desea que genere el código.

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

  3. Recuerde también configurar la ruta correcta al transform_all.batarchivo por lotes.
    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)

Alex Essilfie
fuente
Estoy tratando de usar este enfoque, pero sigo recibiendo un error, con '\ Common fue inesperado en este momento'. en mi salida Sucede en esta línea: for / f "delims =" %% d in (t4list.txt) do ... ¿Alguna idea de lo que me falta?
Michael Lewis el
@MichaelLewis: He revisado el archivo por lotes varias veces sin detectar qué podría estar causando el error. Pruebe amablemente el método propuesto por Seth Reno para ver si genera el mismo error. Mientras tanto, ¿puede publicar su t4list.txtarchivo en PasteBin para que intente ver si su error proviene de allí?
Alex Essilfie
Intenté el enfoque de Seth con el mismo problema ('\ Common era inesperado en este momento'). No puedo publicar el archivo t4list.txt debido a restricciones corporativas, pero consta de una línea y \ Common no aparece en la ruta.
Michael Lewis
@MichaelLewis: Desafortunadamente, si su error ocurre for /f "delims=" %%d in (t4list.txt) do (y las restricciones corporativas le impiden publicar su t4list.txtarchivo, me temo que no hay mucho que pueda hacer para ayudarlo. Realmente quería ayudar a resolver esto, pero parece que será imposible ya que no tengo datos para continuar. Buena suerte para solucionar el problema y recuerde publicar su solución cuando tenga éxito.
Alex Essilfie
¿Es posible hacer lo mismo cuando tt contiene (this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;? Desafortunadamente, obtengo una excepción de referencia nula , cuando ejecuto tt desde fuera de Visual Studio.
Andrey K.
4

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

MadRabbit
fuente
3

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: \ Usuarios \ Documentos \ Visual Studio 2012 \ Complementos \

y te vas.

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;

Matware
fuente
3

Gracias a GitHub.com/Mono/T4 , en este momento puede hacerlo para las compilaciones de .NET Core y Visual Studio agregando esto a su .csprojarchivo:

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

Si transforma sus plantillas a diferentes lenguajes de programación, debe agregar algo como <Compile Remove="**\*.vb" />y <Compile Include="**\*.vb" />para compilar estos archivos, incluso si aún no ha generado archivos.

Removey Includetruco solo necesario para la primera generación, o puede acortar el XML de esta manera:

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

y simplemente ejecuta build dos veces (por primera vez). Si ya ha generado archivos comprometidos con el repositorio, no habrá problemas en las reconstrucciones con ambos ejemplos.

En Visual Studio, es posible que desee ver algo como esto:

ingrese la descripción de la imagen aquí

en lugar de esto:

ingrese la descripción de la imagen aquí

Entonces agregue algo como esto a su archivo de proyecto:

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

Ejemplo completo aquí: GitHub.com/Konard/T4GenericsExample (incluye la generación de múltiples archivos a partir de una sola plantilla).

Konard
fuente
1

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 salida en una línea (:: Puede intentar ....)

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

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

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 configuración = depuración, se asegura de que no regenere el código en el modo de lanzamiento, cuando realiza la compilación en el servidor de compilación TFS, por ejemplo.

anoop
fuente
Agradable, pero transformar todo podría ser peligroso si T4MVC no solo es tt en el proyecto y no queremos ejecutar todo ...
Landeeyo
3
No tengo TextTemplating en la carpeta v11.0. ¿De dónde sacas eso?
Zack
1

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.

usuario1607685
fuente
1
No puedo encontrar esta opción en el menú del botón derecho, sin embargo, de acuerdo con el MSDN, es posible hacerlo editando el archivo del proyecto en VS 2012 y 2013, consulte msdn.microsoft.com/en-us/library/ee847423. aspx o msdn.microsoft.com/en-us/library/vstudio/ee847423.aspx para más detalles
yoel halb
Esta parece ser una opción que viene solo con herramientas tangibles T4, no predeterminadas en Visual Studio.
Matt DiTrolio
Sí, esto es solo en la versión pro de T4 Toolbox.
Pompair
1

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 archivo .targets para usar con archivos de estudio visual.

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

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 para que sean los esperados
  2. Elimine las referencias de ensamblado 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>
    • Primera parte Localiza TextTransform.exe

    • $(IncludeForTransform)será igual a c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dllporque 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í se <InProject>False</InProject>ocultan 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

Georgi
fuente
Agregue la solución en sí a su respuesta para proporcionar más contexto. Los enlaces no son soluciones a la pregunta y pueden estar muertos cuando otros usuarios vuelvan a esta pregunta más tarde.
Frank van Wijk
1

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.

Tim Maes
fuente
1

Simplemente instale NuGet Package: Clarius.TransformOnBuild

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

dqthe
fuente
1

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"

ps Cambia la ruta a tu plantilla si no se encuentra en el directorio raíz del proyecto.

uno al azar
fuente
0

Algún tipo construyó 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; aviso.

EDITAR: Esto terminó siendo mi problema.

Grault
fuente
0

Aquí hay un evento previo a la compilación que utiliza solo herramientas de Microsoft y rutas estándar. Se probó en vs2019 / netcore3.1.

Reemplace "AppDbContext.tt" con su ruta de archivo relativa al proyecto:

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

Microsoft también tiene una guía para hacer que las macros como "$ (SolutionDirectory)" estén disponibles en la plantilla utilizando T4ParameterValues en su archivo de proyecto.

npjohns
fuente