web-dev-qa-db-ja.com

Visual Studioを入手して、ビルドごとにT4テンプレートを実行します

T4テンプレートを取得して、ビルドごとに出力を生成するにはどうすればよいですか?現在は、テンプレートに変更を加えたときにのみ再生成されます。

私はこれに似た他の質問を見つけました:

Visual StudioでのT4変換とビルド順序 (未回答)

Visual Studioでビルドするt4ファイルを取得する方法 (答えは十分に詳細ではなく(まだかなり複雑ですが)、まったく意味がありません)

これを行うにはもっと簡単な方法が必要です!

158
JoelFan

私はJoelFanの答えを使ってこれを思いついた。新しい.ttファイルをプロジェクトに追加するたびに、ビルド前イベントを変更することを覚えておく必要がないので、私はそれがより好きです。

  • textTransform.exeを%PATH%に追加します
  • transform_all.batという名前のバッチファイルを作成しました(以下を参照)
  • ビルド前イベント「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
68
Seth Reno

GarethJに同意します-VS2010では、ビルドごとにttテンプレートを再生成する方がはるかに簡単です。 Oleg Sychのブログでは、その方法について説明しています。要するに:

  1. インストール Visual Studio SDK
  2. インストール Visual Studio 2010 Modeling and Visualization SDK
  3. テキストエディタープロジェクトファイルで開き、ファイルの最後である</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" />
69
Cheburek

これを行う素晴らしいNuGetパッケージがあります:

PM> Install-Package Clarius.TransformOnBuild

パッケージに関する詳細は found here です。

29
GavKilbride

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は、テンプレート内のAssemblyディレクティブによって参照されるDLLへのパスです。

次に、T4テンプレートを含むプロジェクトのプロジェクトプロパティに移動します。 ビルドイベントに移動し、次のビルド前のイベントコマンドラインを追加します。

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

MyTemplateを.tt拡張子なしの.ttファイル(つまりMyTemplate.tt)のファイル名に置き換えます。これにより、プロジェクトをビルドする前にテンプレートを展開してMyTemplate.csを生成する結果になります。その後、実際のビルドはMyTemplate.csをコンパイルします

20
JoelFan

最近、この素晴らしいVSプラグイン Chirpy が見つかりました。

ビルドでT4を生成するだけでなく、javascript、CSSの縮小にT4ベースのアプローチを可能にし、CSSにLESS構文を使用することさえできます!

14
Mark Melville

おそらく最も簡単な方法は、 AutoT4 というVisual Studio拡張機能をインストールすることです。

ビルド時にすべてのT4テンプレートを自動的に実行します。

13
Saul

事前ビルドは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"

もちろん、必要に応じてプロジェクトディレクトリパスを渡すバッチファイルにこれを引き出すことができます。

[〜#〜] nb [〜#〜]パスには微調整が必​​要な場合があります。上記のパスは、VS 2008がマシン上でインストールした場所です。ただし、バージョン番号がTextTemplatingTextTransform.exe 異なります。

12
Peter Taylor

C:\ Program Files(x86)\ Common Files\Microsoft Shared\TextTemplatingをご覧ください。そこにはコマンドライン変換exeがあります。または、カスタムホストを使用してMSBuildタスクを記述し、自分で変換を行います。

9
MarkGr

Seth Reno および JoelFan's の答えを展開して、私はこれを思いつきました。このソリューションでは、プロジェクトに新しい.ttファイルを追加するたびに、ビルド前イベントを変更することを覚えておく必要はありません。

実施手順

  • Transform_all.batという名前のバッチファイルを作成します(以下を参照)
  • ビルドする.ttを使用して、プロジェクトごとにビルド前イベントtransform_all.bat "$(ProjectDir)" $(ProjectExt)を作成します

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
_


[〜#〜] notes [〜#〜]

  1. テキスト変換では、T4テンプレートのコードがプロジェクトタイプと同じ言語であると想定しています。このケースが当てはまらない場合は、$(ProjectExt)引数をコードで生成するファイルの拡張子に置き換える必要があります。

  2. _.TT_ファイルはプロジェクトディレクトリに存在する必要があります。そうでない場合、ビルドされません。最初の引数として別のパスを指定することにより、プロジェクトディレクトリの外部でTTファイルをビルドできます(iereplace "$(ProjectDir)" TTファイルを含むパスを含む)

  3. _transform_all.bat_バッチファイルに正しいパスを設定することも忘れないでください。
    たとえば、ソリューションディレクトリに配置したため、ビルド前のイベントは次のようになりました"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)

7
Alex Essilfie

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

6
GarethJ

ちょっと、私のスクリプトは出力拡張機能も解析できます

_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ファイルが自動的に変換されます。

4
MadRabbit

Dynamo.AutoTTは必要なことを行います。正規表現を介してファイルを監視したり、ビルド時に生成するように構成できます。また、トリガーするT4テンプレートを指定することもできます。

ここからダウンロードできます: https://github.com/MartinF/Dynamo.AutoTT

ビルドして、dllファイルとAddInファイルを

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

離れて行きます。

VS2012で使用するには、Dynamo.AutoTT.AddInファイルを変更し、AddInファイル内でVersionを11.0に設定する必要があります。

3
Matware

これに関する別の良い記事: ビルドプロセスでのコード生成

2012 Modeling and Visualization SDKダウンロードリンク:

https://www.Microsoft.com/en-us/download/details.aspx?id=3068

2
lvanzyl

Mhutchの答えをご覧ください https://stackoverflow.com/a/1395377/9587

私見、これは最高のビルドサーバーと開発環境に優しいオプションです。

2
Ethan J. Brown

このコマンドをプロジェクトのビルド前イベントに追加するだけです。

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

Configuration = debugのチェックでは、たとえばTFSビルドサーバーでビルドを行うときに、リリースモードでコードを再生成しないようにします。

1
anoop

Visual Studio 2013で、T4テンプレートを右クリックし、ビルドプロパティの変換をtrueに設定します。

1
user1607685

ここに私の解決策があります-受け入れられた答えに似ています。ソース管理に問題がありました。ターゲットの.csファイルは読み取り専用であり、T4は失敗していました。一時フォルダーで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)"
1
Ondra

T4Executer はVS2019に対してこれを行います。ビルド時に無視するテンプレートを指定でき、ビルド後実行オプションがあります。

1
Epsilekt

これが私がどのようにタックしたかです。 リンク 。基本的に素晴らしいブログの上に構築する(blogs.clariusconsulting.net/kzu/how-to-transform-t4-templates-on-build-without-installing-a-visual-studio-sdk/はそれ以上投稿できないリンク:()私はこれを思いついた 。targets Visual Studio PROJファイルで使用するファイル。

.tt内で他のdll-sを使用していて、dll-sの変更に合わせて結果を変更したい場合に便利です。

使い方:

  1. Ttを作成し、Assembly name = "$(SolutionDir)path\to\other\project\output\foo.dllを追加し、変換と結果を期待どおりに設定します
  2. .ttからアセンブリ参照を削除します

  3. 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, '&amp;quot; -r &amp;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="&quot;$(_TransformExe)&quot; &quot;@(_TextTransform)&quot; -r &quot;$(IncludeForTransform)&quot;" Condition="'%(Identity)' != ''" />
       </Target>
      _
    • <_TextTransform Include="$(ProjectDir)**\*.tt" /> thisは、プロジェクトおよびサブディレクトリ内のすべての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"_のような行を生成します

  4. あとは、次の内部の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でアセンブリ参照を削除したため

1
Georgi

NuGetパッケージをインストールするだけです:Clarius.TransformOnBuild

次に、再構築プロジェクト(またはソリューション)をクリックするたびに、。ttファイルが実行されます

0
dqthe

Visual Studio 2017(おそらく次のバージョンでも)では、ビルド前イベントにこれを追加する必要があります。

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

追伸ルートプロジェクトディレクトリにない場合は、テンプレートへのパスを変更します。

0
random one

誰か このために nugetパッケージ を構築しました。

サイドノート:TextTemplate.exeとそのパッケージの両方からコンパイルエラーが発生します(そのパッケージはTextTemplate.exeを呼び出すため)。ただし、Visual Studioからは発生しません。したがって、明らかに動作は同じではありません。注意喚起。

編集: これ は私の問題でした。

0
Grault