すべてのビルドで出力を生成するT4テンプレートを取得するにはどうすればよいですか?現状では、テンプレートを変更したときにのみ再生成されます。
私はこれに類似した他の質問を見つけました:
Visual StudioでのT4変換とビルド順序(未回答)
Visual StudioでビルドするT4ファイルを取得するにはどうすればよいですか?(答えは十分に詳細ではありません[まだかなり複雑ですが]、完全に意味がありません)
これを行うには、より簡単な方法が必要です!
すべてのビルドで出力を生成するT4テンプレートを取得するにはどうすればよいですか?現状では、テンプレートを変更したときにのみ再生成されます。
私はこれに類似した他の質問を見つけました:
Visual StudioでのT4変換とビルド順序(未回答)
Visual StudioでビルドするT4ファイルを取得するにはどうすればよいですか?(答えは十分に詳細ではありません[まだかなり複雑ですが]、完全に意味がありません)
これを行うには、より簡単な方法が必要です!
回答:
私はJoelFanの答えを使ってこれを思い付きました。プロジェクトに新しい.ttファイルを追加するたびにビルド前のイベントを変更する必要がないので、私はそれが好きです。
%PATH%
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
"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe"
%PATH%に追加するのではなく、バッチファイルにTextTransform.exe()への完全なパスを配置することをお
%COMMONPROGRAMFILES(x86)%\microsoft shared\TextTemplating\11.0\TextTransform.exe
。二重引用符で囲みます。
TextTransform.exe
吸い込みへの道を提供する必要があります。Visual Studioで[カスタムツールの実行]を既に右クリックできるので、ツールのパスが既にあります。Visual Studioコンテキストからビルドしているときに、再度提供する必要があるのはなぜですか?
GarethJに同意します-VS2010では、ビルドごとにttテンプレートを再生成する方がはるかに簡単です。Oleg Sychのブログでは、その方法について説明しています。要するに:
</Project>
それでおしまい。プロジェクトを開きます。ビルドごとに、すべての* .ttテンプレートが再処理されます
<!-- 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" />
msbuild mySolution.sln /p:CustomAfterMicrosoftCommonTargets="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" /p:TransformOnBuild=true /p:TransformOutOfDateOnly=false
content
<#@ template language="C#" #>
MarkGrの答えを使用して、このソリューションを開発しました。最初に、メインソリューションフォルダーの上の別のtoolsフォルダーにRunTemplate.batというバッチファイルを作成します。バッチファイルには次の行があります。
"%CommonProgramFiles%\Microsoft Shared\TextTemplating\1.2\texttransform.exe" -out %1.cs -P %2 -P "%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5" %1.tt
このバッチファイルは2つのパラメーターを取ります... %1は.tt拡張子なしの.ttファイルへのパスです。 %2は、テンプレートのアセンブリディレクティブによって参照されるDLLへのパスです。
次に、T4テンプレートを含むプロジェクトのプロジェクトプロパティに移動します。ビルドイベントに移動して、次のビルド前イベントコマンドラインを追加します。
$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)
MyTemplateを、.tt拡張子なしの.ttファイル(つまり、MyTemplate.tt)のファイル名に置き換えます。これは、プロジェクトをビルドする前にテンプレートを拡張してMyTemplate.csを生成する結果になります。次に、実際のビルドはMyTemplate.csをコンパイルします
事前ビルドを1行に減らすことができます。
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
これはすべてを変える .tt
、プロジェクト内のファイルがれ、ビルド出力にリストされます。
ビルド出力が不要な場合は、「興味深い動作」を回避する必要があります。
forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c @\"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
もちろん、必要に応じて、プロジェクトディレクトリパスを渡すバッチファイルにこれを引き出すことができます。
注意:パスには微調整が必要な場合があります。上記のパスは、VS 2008が私のマシンにインストールした場所です。ただし、TextTemplating
との間のバージョン番号TextTransform.exe
が異なる場合があります。
System.Exception: T4MVC can only execute through the Visual Studio host
C:\ Program Files(x86)\ Common Files \ Microsoft Shared \ TextTemplatingを確認してください。コマンドライン変換exeがそこにあります。または、カスタムホストを使用してMSBuildタスクを記述し、自分で変換を行います。
拡大セス・レノとJoelFanさん答えて、私はこれを思いつきました。このソリューションでは、プロジェクトに新しい.ttファイルを追加するたびに事前ビルドイベントを変更することを覚えておく必要はありません。
transform_all.bat "$(ProjectDir)" $(ProjectExt)
する.ttを使用して、各プロジェクトのビルド前イベントを作成します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
ノート
テキスト変換では、T4テンプレートのコードがプロジェクトタイプと同じ言語であると想定しています。このケースが当てはまらない場合は、$(ProjectExt)
引数を、コードで生成するファイルの拡張子に置き換える必要があります。
.TT
ファイルはプロジェクトディレクトリにある必要があります。そうしないとビルドされません。最初の引数として別のパスを指定することで、TTファイルをプロジェクトディレクトリの外に構築できます(つまり"$(ProjectDir)"
、TTファイルを含むパスに置き換えます)。
transform_all.bat
バッチファイルへの正しいパスを設定することも忘れないでください。
たとえば、ソリューションディレクトリに配置したので、ビルド前のイベントは次のようになりました"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)
t4list.txt
ファイルをPasteBinに投稿してください。エラーがそこから発生しているかどうかを確認しますか?
for /f "delims=" %%d in (t4list.txt) do (
、企業の制限によりt4list.txt
ファイルを投稿できない場合、私はあなたを助けるためにできることはあまりないと思います。私は本当にこれを解決したいと思っていましたが、続行するデータがないのでそれは不可能になりそうです。問題を解決するために頑張ってください。成功したらソリューションを投稿してください。
(this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
ですか?残念ながら、ビジュアルスタジオ内からではなくttを実行すると、null参照例外が発生します。
Visual Studio 2010を使用している場合は、Visual Studio Modeling and Visualization SDKを使用できます。http: //code.msdn.microsoft.com/vsvmsdk
これには、ビルド時にT4テンプレートを実行するためのmsbuildタスクが含まれています。
詳細については、Olegのブログをご覧ください。http: //www.olegsych.com/2010/04/understanding-t4-msbuild-integration
ねえ、私のスクリプトは出力拡張機能も解析できます
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%
transform_all.bat $(SolutionDir)
ビルド前のイベントを作成するだけで、ソリューション内のすべての* .ttファイルが自動的に変換されます。
Dynamo.AutoTTが必要なことを行います。正規表現を介してファイルを監視するか、ビルド時に生成するように構成できます。また、トリガーするT4テンプレートを指定することもできます。
こちらからダウンロードできます:https : //github.com/MartinF/Dynamo.AutoTT
ビルドして、dllファイルとAddInファイルを
C:\ Users \ Documents \ Visual Studio 2012 \ Addins \
離れて行きます。
VS2012でそれを実行したい場合は、Dynamo.AutoTT.AddInファイルを変更し、AddInファイル内のバージョンを11.0に設定する必要があります。
GitHub.com/Mono/T4のおかげで、現時点では、これを.csproj
ファイルに追加することで、.NET CoreビルドとVisual Studioビルドの両方で実行できます。
<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>
テンプレートを別のプログラミング言語に変換する場合は、次のようなものを追加する必要が<Compile Remove="**\*.vb" />
あります<Compile Include="**\*.vb" />
あなたはまだファイルが生成されていない場合でも、コンパイルされ、これらのファイルを入手するために。
Remove
そしてInclude
トリックは初回のみの世代のために必要な、またはあなたは、このようなXMLは、短くすることができます。
<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>
ビルドを2回実行します(初めて)。リポジトリにコミットされたファイルをすでに生成している場合は、両方の例を使用して再構築しても問題はありません。
Visual Studioでは、次のようなものを表示することができます。
これの代わりに:
したがって、次のようなものをプロジェクトファイルに追加します。
<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>
ここに完全な例:GitHub.com/Konard/T4GenericsExample(単一のテンプレートからの複数のファイルの生成を含む)。
これが私の解決策です-受け入れられた答えに似ています。ソース管理に問題がありました。ターゲットの.csファイルは読み取り専用で、T4は失敗していました。これは、tempフォルダーでT4を実行し、ターゲットファイルを比較し、同じ変更の場合にのみコピーするコードです。read.onlyファイルの問題は修正されませんが、少なくともそれほど頻繁には発生しません。
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
行にチェックアウトコマンドを追加することができます(::試すことができます....)
プロジェクトで、これを事前構築アクションとして設定します。
Path-To-Transform.bat "$(ProjectDir)"
このコマンドをプロジェクトの事前ビルドイベントに追加するだけです。
if $(ConfigurationName) == Debug $(MSBuildToolsPath)\Msbuild.exe /p:CustomBeforeMicrosoftCSharpTargets="$(ProgramFiles)\MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets" $(ProjectPath) /t:TransformAll
configuration = debugのチェックは、たとえばTFSビルドサーバーでビルドを行うときに、リリースモードでコードを再生成しないことを確認します。
Visual Studio 2013で、T4テンプレートを右クリックし、ビルドプロパティの変換をtrueに設定します。
これが私がそれに取り組んだ方法です。リンク。基本的に素晴らしいブログの上に構築する(blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/ can not post post more 2リンク:()この.targetsを思いついた Visual Studioのprojファイルで使用するためのファイルを。
.tt内で他のdll-sを使用していて、dll-sの変更に伴って結果を変更したい場合に便利です。
使い方:
.ttからアセンブリ参照を削除する
projファイル内で、次のコードを使用してビルド時に変換を設定します。
<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>
最初の部分はTextTransform.exeを探します
$(IncludeForTransform)
これはc:\path\to\dll\foo.dll' -r c:\path\to\dll\bar.dll
、コマンドラインでTextTransformの参照を追加する方法だからです。
<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" />
これにより、プロジェクトとサブディレクトリ内のすべてのttファイルのリストが作成されます
<Exec Command="...
見つかった各.ttファイルに対して次のような行を生成します "C:\path\to\Transform.exe" "c:\path\to\my\proj\TransformFile.tt" -r"c:\path\to\foo.dll" -r "c:\path\to\bar.dll"
あとは、次の場所にDLLへのパスを追加するだけです。
<ItemGroup>
<DllsToInclude Include="$(ProjectDir)path\to\foo.dll">
<InProject>False</InProject>
</DllsToInclude>
<DllsToInclude Include="$(ProjectDir)path\to\bar.dll">
<InProject>False</InProject>
</DllsToInclude>
</ItemGroup>
ここで<InProject>False</InProject>
は、ソリューションビューからこれらのアイテムを非表示にします
これで、ビルド時とdll-sの変更時にコードを生成できるようになります。
カスタムツールを(Visual Studio内のプロパティから)削除して、VSが毎回変身したり失敗したりしないようにすることができます。手順2でアセンブリ参照を削除したため
T4ExecuterはVS2019でこれを行います。ビルド時に無視するテンプレートを指定でき、ビルド後の実行オプションがあります。
ある人はnugetパッケージを作りましたこのために。
補足:TextTemplate.exeとそのパッケージの両方からコンパイルエラーが発生します(そのパッケージはTextTemplate.exeを呼び出すため)。VisualStudioからはそうではありません。明らかに、動作は同じではありません。注意喚起。
編集:これは結局私の問題でした。
以下は、Microsoft Toolingと標準パスのみを使用したビルド前のイベントです。vs2019 / netcore3.1でテストされています。
「AppDbContext.tt」をプロジェクトの相対ファイルパスに置き換えます。
"$(MSBuildBinPath)\msbuild" $(SolutionPath) /t:$(ProjectName):Transform /p:TransformFile="AppDbContext.tt" /p:CustomAfterMicrosoftCommonTargets="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets"
Microsoftには、「$(SolutionDirectory)」のようなマクロをテンプレートで使用できるようにするためのガイドもあります プロジェクトファイルでT4ParameterValuesをます。