获取Visual Studio以在每个构建上运行T4模板

Joe*_*Fan 159 msbuild tfs t4 visual-studio

如何获得T4模板以在每次构建时生成其输出?就像现在一样,它只在我对模板进行更改时才重新生成它.

我发现了类似的其他问题:

Visual Studio中的T4转换和构建顺序(未答复)

如何在Visual Studio中构建t4文件?(答案不够详细[虽然仍然很复杂]甚至没有完全意义)

必须有一个更简单的方法来做到这一点!

Che*_*rek 69

我同意GarethJ - 在VS2010中,在每个构建上重新生成tt模板要容易得多.Oleg Sych的博客描述了如何做到这一点.简而言之:

  1. 安装Visual Studio SDK
  2. 安装Visual Studio 2010建模和可视化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" />
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的解决方案.但是有没有办法让这个工作无需安装SDK?我一直试图通过复制.targets文件和相关程序集来使它工作,但没有成功. (4认同)
  • Chirpy似乎无需下载任何SDK即可运行...但是,您仍然需要下载和配置Chirpy.我仍在尝试发现一个适用于VS2010默认安装的解决方案,并且可以通过源存储库获得,这样开发人员只需要检查repo就可以了.所有这些其他解决方案都需要过多的开发人员注意力. (3认同)
  • 而且,您不需要修补.csproj文件.从命令行调用类似`msbuild mySolution.sln/p:CustomAfterMicrosoftCommonTargets ="C:\ Program Files(x86)\ MSBuild\Microsoft\VisualStudio\v11.0\TextTemplating\Microsoft.TextTemplating.targets"/ p:TransformOnBuild = true/p:TransformOutOfDateOnly = false` (3认同)
  • 安装整个 SDK 只是为了生成可以在 Visual Studio 中默认执行的文本模板,这是完全荒谬的。 (3认同)
  • 这是Oleg Sych博客文章的链接:http://www.olegsych.com/2010/04/understanding-t4-msbuild-integration/ (2认同)
  • 如果您使用 x64 版本的 MSBuild 构建项目 - 您将收到此错误:'MSB4019:导入的项目“C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets “ 没有找到。' 错误。解决方法 - 在项目文件中用 $(MSBuildExtensionsPath32) 替换 $(MSBuildExtensionsPath) 变量。 (2认同)
  • @PhilChuang:Oleg Sych 博客文章的回溯机链接:https://web.archive.org/web/20110816220543/http://olegsych.com/2010/04/understanding-t4-msbuild-integration/ (2认同)

Set*_*eno 68

我用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
Run Code Online (Sandbox Code Playgroud)

  • 好的解决方案 我更喜欢在批处理文件中放置TextTransform.exe(`%CommonProgramFiles%\ Microsoft Shared\TextTemplating\1.2\texttransform.exe"`)的完整路径,而不是将其添加到%PATH% (28认同)
  • 一个更好的变量是%COMMONPROGRAMFILES(x86)%而不是%COMMONPROGRAMFILES%,因为它也适用于64位系统. (20认同)
  • 所以完整路径将是`%COMMONPROGRAMFILES(x86)%\ microsoft shared\TextTemplating\11.0\TextTransform.exe`.用双引号括起来. (3认同)

Gav*_*ide 29

有一个很好的NuGet包可以做到这一点:

PM> Install-Package Clarius.TransformOnBuild
Run Code Online (Sandbox Code Playgroud)

有关该包的详细信息,请访问此处

  • 有一个'非官方的'分支:https://www.nuget.org/packages/Clarius.TransformOnBuild-unofficial支持`content`构建操作 (2认同)
  • @JenishRabadiya 将此行添加到模板顶部:`&lt;#@ template language="C#" #&gt;` (2认同)
  • 似乎该软件包已更新为支持** hostspecific =“ true” **和其他问题(8天前) (2认同)

Joe*_*Fan 20

我使用MarkGr的答案并开发了这个解决方案.首先,在主解决方案文件夹上方的单独工具文件夹中创建一个名为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
Run Code Online (Sandbox Code Playgroud)

此批处理文件有2个参数... %1是没有.tt扩展名的.tt文件的路径. %2是模板中Assembly指令引用的任何DLL的路径.

接下来,进入包含T4模板的项目的Project Properties.进入构建事件并添加以下预构建事件命令行:

$(SolutionDir)..\..\tools\RunTemplate.bat $(ProjectDir)MyTemplate $(OutDir)
Run Code Online (Sandbox Code Playgroud)

用.tt文件的文件名替换MyTemplate(即MyTemplate.tt),不带.tt扩展名.这将导致在构建项目之前扩展模板以生成MyTemplate.cs.然后实际的构建将编译MyTemplate.cs


Mar*_*lle 14

最近发现这个伟大的VS插件,Chirpy.

它不仅可以在构建中生成T4,而且它允许基于T4的方法来缩小javascript,CSS,甚至允许您为CSS使用LESS语法!


Sau*_*aul 13

可能最简单的方法是安装名为AutoT4的Visual Studio扩展.

它在构建时自动运行所有T4模板.


Pet*_*lor 12

预构建可以简化为一行:

forfiles /p "$(ProjectDir)." /m "*.tt" /s /c "cmd /c echo Transforming @path && \"%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\1.2\TextTransform.exe\" @file"
Run Code Online (Sandbox Code Playgroud)

这将转换.tt项目中的所有文件,并将它们列入构建输出.

如果你不想要构建输出那么你必须解决一些"有趣的行为":

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

当然,如果您愿意,可以将其拉出到您传递项目目录路径的批处理文件中.

NB路径可能需要一些调整.上面的路径是VS 2008在我的机器上安装它的地方; 但你可能会发现,之间的版本号TextTemplatingTextTransform.exe是不同的.


Mar*_*kGr 9

看看C:\ Program Files(x86)\ Common Files\Microsoft Shared\TextTemplating那里有一个命令行转换exe.或者,使用自定义主机编写MSBuild任务并自行进行转换.


Kon*_*ard 8

感谢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>
Run Code Online (Sandbox Code Playgroud)

如果您将模板转换为不同的编程语言,您应该添加类似<Compile Remove="**\*.vb" />和 的内容<Compile Include="**\*.vb" />,以便即使您还没有生成文件也能编译这些文件。

RemoveInclude技巧只需要第一次生成,或者你可以像这样使 XML-shorter:

  <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>
Run Code Online (Sandbox Code Playgroud)

并且只运行构建两次(第一次)。如果您已经将生成的文件提交到存储库,则两个示例的重建都不会出现问题。

在 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>
Run Code Online (Sandbox Code Playgroud)

完整示例在此:GitHub.com/Konard/T4GenericsExample(包括从单个模板生成多个文件)。


Ale*_*fie 7

扩展了Seth RenoJoelFan的答案,我想出了这个.使用此解决方案时,无需记住每次向项目添加新的.tt文件时都要修改预构建事件.

实施程序

  • 创建名为transform_all.bat的批处理文件(见下文)
  • 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
Run Code Online (Sandbox Code Playgroud)


笔记

  1. 文本转换假定T4模板中的代码与项目类型的语言相同.如果这种情况不适用于您,则必须将$(ProjectExt)参数替换为您希望代码生成的文件的扩展名.

  2. .TT文件必须位于项目目录中,否则它们将无法构建.您可以通过指定不同的路径作为第一个参数来构建项目目录之外的TT文件(替换"$(ProjectDir)"为包含TT文件的路径.)

  3. 还要记住设置transform_all.bat批处理文件的正确路径.
    例如,我将它放在我的解决方案目录中,因此预构建事件如下所示"$(SolutionDir)transform_all.bat" "$(ProjectDir)" $(ProjectExt)


Gar*_*thJ 6

如果您使用的是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


ran*_*one 6

在 Visual Studio 2017(也可能是下一个版本)中,您应该在预构建事件中添加以下内容:

"$(DevEnvDir)TextTransform.exe" -out "$(ProjectDir)YourTemplate.cs" "$(ProjectDir)YourTemplate.tt"
Run Code Online (Sandbox Code Playgroud)

ps 如果模板不在根项目目录中,请更改模板的路径。