Wie erhalte ich eine T4-Vorlage, um die Ausgabe bei jedem Build zu generieren? Wie es jetzt ist, wird es nur neu generiert, wenn ich eine Änderung an der Vorlage vornehme.
Ich habe ähnliche Fragen gefunden:
T4-Transformation und Erstellungsreihenfolge in Visual Studio (unbeantwortet)
Wie bekomme ich T4-Dateien, um sie in Visual Studio zu erstellen? (Die Antworten sind nicht detailliert genug (obwohl sie immer noch ziemlich kompliziert sind) und ergeben nicht einmal einen Sinn.)
Es muss einen einfacheren Weg geben, dies zu tun!
Ich habe die Antwort von JoelFan benutzt, um darauf zu kommen. Mir gefällt es besser, weil Sie nicht jedes Mal daran denken müssen, das Pre-Build-Ereignis zu ändern, wenn Sie dem Projekt eine neue .tt-Datei hinzufügen.
%PATH%
hinzutransform_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
Ich stimme GarethJ zu - in VS2010 ist es viel einfacher, TT-Vorlagen für jeden Build neu zu generieren. Oleg Sychs Blog beschreibt, wie es geht. Zusamenfassend:
</Project>
Das ist es. Öffnen Sie Ihr Projekt. Bei jedem Build werden alle * .tt-Vorlagen erneut verarbeitet
<!-- 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" />
Es gibt ein großartiges NuGet-Paket, das genau dies leistet:
PM> Install-Package Clarius.TransformOnBuild
Details zum Paket können hier zu finden
Ich habe MarkGrs Antwort verwendet und diese Lösung entwickelt. Erstellen Sie zunächst eine Batchdatei mit dem Namen RunTemplate.bat in einem separaten tools Ordner über dem Hauptlösungsordner. Die Batch-Datei hat nur die folgende Zeile:
"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt
Diese Batch-Datei akzeptiert 2 Parameter ... % 1 ist der Pfad zur .tt-Datei ohne die Erweiterung .tt. % 2 ist der Pfad zu allen DLLs, auf die durch Assembly -Anweisungen in der Vorlage verwiesen wird.
Gehen Sie als nächstes in die Projekteigenschaften des Projekts, das die T4-Vorlage enthält. Gehen Sie zu Build Events und fügen Sie Folgendes hinzu Befehlszeile für das Pre-Build-Ereignis:
$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)
ersetzen von MyTemplate durch den Dateinamen Ihrer .tt-Datei (d. h. MyTemplate.tt) ohne die Erweiterung .tt. Dies hat zur Folge, dass die Vorlage vor dem Erstellen des Projekts so erweitert wird, dass MyTemplate.cs erstellt wird. Der eigentliche Build kompiliert dann MyTemplate.cs
Kürzlich wurde dieses großartige VS-Plugin gefunden, Chirpy .
Es generiert nicht nur Ihren T4 für einen Build, sondern ermöglicht auch einen T4-basierten Ansatz zur Minimierung von Javascript, CSS und ermöglicht sogar die Verwendung von WENIGER-Syntax für Ihr CSS!
Der wahrscheinlich einfachste Weg ist die Installation einer Visual Studio-Erweiterung mit dem Namen AutoT4 .
Alle T4-Templates werden automatisch erstellt.
Der Pre-Build kann auf eine einzelne Zeile reduziert werden:
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Dies transformiert alle .tt
Dateien im Projekt und listet sie in der Build-Ausgabe auf.
Wenn Sie die Build-Ausgabe nicht wollen, müssen Sie einiges umgehen "interessantes Verhalten" :
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Natürlich können Sie dies in eine Batch-Datei ziehen, an die Sie den Projektverzeichnispfad übergeben, wenn Sie dies wünschen.
[~ # ~] nb [~ # ~] Der Pfad muss möglicherweise angepasst werden. Im obigen Pfad ist VS 2008 auf meinem Computer installiert. aber Sie könnten feststellen, dass die Versionsnummer zwischen TextTemplating
und TextTransform.exe
ist anders.
Checken Sie C:\Programme (x86)\Gemeinsame Dateien\Microsoft Shared\TextTemplating aus. Alternativ können Sie eine MSBuild-Aufgabe mit einem benutzerdefinierten Host schreiben und die Transformation selbst durchführen.
Als ich die Antworten Seth Reno und JoelFan's erweitere, habe ich mir das ausgedacht. Mit dieser Lösung müssen Sie nicht jedes Mal daran denken, das Pre-Build-Ereignis zu ändern, wenn Sie dem Projekt eine neue .tt-Datei hinzufügen.
transform_all.bat "$(ProjectDir)" $(ProjectExt)
für jedes Projekt mit einer .tt-Datei, die Sie erstellen möchtentransform_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
[~ # ~] Notizen [~ # ~]
Bei der Textumwandlung wird davon ausgegangen, dass der Code in der T4-Vorlage dieselbe Sprache wie Ihr Projekttyp hat. Wenn dieser Fall für Sie nicht zutrifft, müssen Sie das Argument $(ProjectExt)
durch die Erweiterung der Dateien ersetzen, die der Code generieren soll.
.TT
- Dateien müssen sich im Projektverzeichnis befinden, sonst werden sie nicht erstellt. Sie können TT Dateien außerhalb des Projektverzeichnisses erstellen, indem Sie als erstes Argument einen anderen Pfad angeben ( dh replace "$(ProjectDir)"
mit dem Pfad, der die TT Dateien enthält.)
Denken Sie auch daran, den richtigen Pfad zur Batch-Datei transform_all.bat
Festzulegen.
Ich habe es beispielsweise in mein Lösungsverzeichnis gestellt, sodass das Pre-Build-Ereignis wie folgt lautete: "$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)
Wenn Sie Visual Studio 2010 verwenden, können Sie das Visual Studio-SDK für Modellierung und Visualisierung verwenden: http://code.msdn.Microsoft.com/vsvmsdk
Dies enthält msbuild-Tasks zum Ausführen von T4-Vorlagen zum Zeitpunkt der Erstellung.
Weitere Erklärungen finden Sie in Olegs Blog: http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration
Hey, mein Skript kann auch die Ausgabeerweiterung analysieren
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%
Erstellen Sie einfach ein transform_all.bat $(SolutionDir)
-Ereignis, und alle * .tt-Dateien in Ihrer Lösung werden automatisch transformiert.
Dynamo.AutoTT macht das, was Sie brauchen. Sie können es so konfigurieren, dass es Dateien über einen regulären Ausdruck überwacht oder beim Erstellen generiert. Hier können Sie auch angeben, welche T4-Vorlagen ausgelöst werden sollen.
Sie können es hier herunterladen: https://github.com/MartinF/Dynamo.AutoTT
Erstellen Sie es einfach, kopieren Sie die DLL- und AddIn-Dateien in
C:\Benutzer\Dokumente\Visual Studio 2012\Addins \
und los gehts.
Wenn Sie VS2012 verwenden möchten, müssen Sie die Datei Dynamo.AutoTT.AddIn ändern und die Version in der AddIn-Datei auf 11.0 festlegen.
Ein weiterer guter Artikel dazu: Codegenerierung in einem Build-Prozess
Download-Link für das Modellierungs- und Visualisierungs-SDK 2012:
https://www.Microsoft.com/en-us/download/details.aspx?id=3068
Bitte lesen Sie die Antwort von mhutch https://stackoverflow.com/a/1395377/9587
IMHO, das ist die beste Build-Server und dev umweltfreundliche Option.
Sie müssen nur diesen Befehl zum Pre-Build-Ereignis des Projekts hinzufügen:
if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" $(ProjectPath) /t:TransformAll
Die Prüfung auf configuration = debug stellt sicher, dass Sie den Code im Release-Modus nicht neu generieren, wenn Sie beispielsweise den Build auf dem TFS-Build-Server ausführen.
Klicken Sie in Visual Studio 2013 mit der rechten Maustaste auf die T4-Vorlage und setzen Sie die Eigenschaft transform on build auf true.
Hier ist meine Lösung - ähnlich wie die akzeptierte Antwort. Wir hatten ein Problem mit unserer Quellcodeverwaltung. Die CS-Zieldateien sind schreibgeschützt und der T4 schlug fehl. Hier ist der Code, der T4 im temporären Ordner ausführt, Zieldateien vergleicht und nur bei gleicher Änderung kopiert. Es behebt das Problem mit read.only-Dateien nicht, aber zumindest tritt es nicht sehr oft auf:
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
Sie können versuchen, Ihren Check-Out-Befehl in eine Zeile einzufügen (:: Sie können es versuchen ...)
Stellen Sie dies in Ihrem Projekt als vorbereitende Aktion ein:
Path-To-Transform.bat "$(ProjectDir)"
T4Executer erledigt dies für VS2019. Sie können Vorlagen angeben, die beim Erstellen ignoriert werden sollen, und es gibt eine Option zum Ausführen nach dem Erstellen.
Hier ist, wie ich es angepackt habe. Link . Aufbauend auf einem großartigen Blog (blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ kann nicht mehr als 2 posten Links :() Ich habe mir diese . Targets Datei ausgedacht, um sie mit Visual Studio ProJ-Dateien zu verwenden.
Dies ist nützlich, wenn Sie andere DLLs in Ihrer .tt-Datei verwenden und das Ergebnis ändern möchten, während sich die DLLs ändern.
Wie es funktioniert:
Entfernen Sie die Assemblyverweise von .tt
Verwenden Sie in der proj-Datei diesen Code, um die Transformation beim Erstellen einzurichten:
<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, '&quot; -r &quot;')</IncludeForTransform>
</PropertyGroup>
Erster Teil Findet TextTransform.exe
$(IncludeForTransform)
ist gleich c:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll
, da auf diese Weise Referenzen für die TextTransform in der Befehlszeile hinzugefügt werden können
<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=""$(_TransformExe)" "@(_TextTransform)" -r "$(IncludeForTransform)"" Condition="'%(Identity)' != ''" />
</Target>
<_TextTransform Include="$(ProjectDir)**\*.tt" />
erstellt eine Liste aller tt-Dateien im Projekt und in den Unterverzeichnissen
<Exec Command="...
Erzeugt eine Zeile für jede der gefundenen .tt-Dateien, die aussieht wie "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll"
Sie müssen nur noch die Pfade zu den DLLs in hinzufügen:
<ItemGroup>
<DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
<InProject>False</InProject>
</DllsToInclude>
<DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
<InProject>False</InProject>
</DllsToInclude>
</ItemGroup>
Hier versteckt <InProject>False</InProject>
Diese Elemente in der Lösungsansicht
Jetzt sollten Sie in der Lage sein, Ihren Code beim Erstellen und Ändern von DLLs zu generieren.
Sie können das benutzerdefinierte Tool (aus den Eigenschaften in Visual Studio) entfernen, damit der VS nicht jedes Mal versucht, das Tool zu transformieren und einen Fehler zu verursachen. Weil wir die Assembly-Referenzen in Schritt 2 entfernt haben
Sie installieren einfach das NuGet-Paket: Clarius.TransformOnBuild
Jedes Mal, wenn Sie auf Neu erstellen Projekt (oder Projektmappe) klicken, werden Ihre . Tt Dateien ausgeführt
In Visual Studio 2017 (wahrscheinlich auch in den nächsten Versionen) sollten Sie dies im Pre-Build-Ereignis hinzufügen:
"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"
p.s. Ändern Sie den Pfad zu Ihrer Vorlage, wenn sich diese nicht im Stammverzeichnis des Projekts befindet.
Ein Typ hat dafür ein Nuget-Paket erstellt.
Anmerkung: Ich erhalte Kompilierungsfehler sowohl von TextTemplate.exe als auch von diesem Paket (da dieses Paket TextTemplate.exe aufruft), jedoch nicht von Visual Studio. Anscheinend ist das Verhalten also nicht dasselbe. Kopf hoch.
BEARBEITEN: Dies endete als mein Problem.