Understanding T4: MSBuild Integration


Visual Studio 2010 offers a new capability to perform template-based code generation at build-time with a set of MSBuild extensions available as part of the Visualization and Modeling SDK.

Contents

Overview

Since its initial release, T4 has followed a well-established pattern of integrating code generators in Visual Studio and providing two different ways to generate code. The first and primary method of triggering template transformation process is at design time, by saving the template file. When a template (.tt) file is added to a C# or Visual Basic project, it is automatically associated with a custom tool called TextTemplatingFileGenerator. Visual Studio invokes the custom tool whenever the associated file is saved, causing the output file to be regenerated whenever the template file is modified. The second and alternative method of triggering template transformation process is at build time, with a command line utility called TextTransform. In order to generate code at build time, a developer needs to modify the MSBuild definition of a Visual Studio project and invoke this command utility for each of the template files that need to be transformed.

The main benefits of design-time code generation are its simplicity and automatic addition of the generated files in Visual Studio projects and source control. This approach works well when template files are self contained. However, when templates include other files or use external sources of metadata, such as model files or databases, the generated files may become out of date even if their templates don’t change. Build-time code generation ensures that output files are always current and makes sense in complex scenarios when keeping track of multiple templates becomes error prone. The main drawbacks of build-time code generation are the additional effort required to implement it, and more importantly, the set of challenges it presents around integration with Visual Studio projects and source control.

Visual Studio 2010 offers a new option for generating code from text templates at build time. This capability is implemented as a set of MSBuild tasks and targets that come with the Visual Studio Modeling and Visualization SDK. Here is where the files are located.

C:\>dir "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0" /b
Microsoft.TextTemplating.Build.Tasks.dll
Microsoft.TextTemplating.targets
Microsoft.VisualStudio.TextTemplating.Sdk.Host.10.0.dll

The new MSBuild integration feature of T4 significantly reduces the effort required to implement and maintain build-time code generation and solves some of the challenges around integration with Visual Studio projects and source control.

Configuring project for build-time template transformation

In order to configure a Visual Studio project for build-time template transformation, you have to manually modify the MSBuild definition in the project file. At a minimum, you need to import Microsoft.TextTemplating.targets file and set TransformOnBuild property to true. Here is an extract from a C# project file that was modified this way.

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
  <TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

Note that Microsoft.TextTemplating.targets file has to be imported after the standard import – Microsoft.CSharp.targets for C# or Microsoft.VisualBasic.targets for Visual Basic projects. The TransformOnBuild variable can be defined anywhere in the file, such as in the main PropertyGroup of the project.

Here is a typical output you will see when building a customized project.

------ Build started: Project: T4MSBuild, Configuration: Debug x86 ------
Build started 4/10/2010 1:30:38 PM.
ExecuteTransformations:
  Performing incremental T4 transformation
  Calculating whether transformed output is out of date...
  Transforming template Template.tt...
  Performing incremental T4 preprocessing
  Calculating whether preprocessed output is out of date...
  Preprocessing template PreprocessedTemplate.tt...
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreCompile:
  C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /platform:x86 /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" /debug+ /out:obj\x86\Debug\T4MSBuild.dll /target:library PreprocessedTemplate.cs Template.cs "C:\Users\osych\AppData\Local\Temp\.NETFramework,Version=v4.0.AssemblyAttributes.cs"
CopyFilesToOutputDirectory:
  Copying file from "obj\x86\Debug\T4MSBuild.dll" to "bin\Debug\T4MSBuild.dll".
  T4MSBuild -> C:\T4MSBuild\T4MSBuild\bin\Debug\T4MSBuild.dll
  Copying file from "obj\x86\Debug\T4MSBuild.pdb" to "bin\Debug\T4MSBuild.pdb".

Build succeeded.

Time Elapsed 00:00:00.55
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

In this sample output, note that a file called Template.tt was transformed and another file called PreprocessedTemplate.tt was preprocessed. In other words, the MSBuild functionality fully supports the preprocessed templates introduced in Visual Studio 2010.

Under the hood

When imported, Microsoft.TextTemplating.targets file modifies the normal project build process defined in Microsoft.Common.targets by inserting the following steps (targets) in the beginning of the build sequence.

  • Create a list of candidate files for transformation
  • Execute user-defined target before transformation
  • Select template files for processing
  • Transform and/or preprocess templates
  • Execute user-defined target after transformation

T4 creates a list of candidate files for transformation by selecting all files in the project that have build action of None, Compile, Content or EmbeddedResource. Normally, .tt files have build action of None and get included automatically.

After the initial list of candidate files has been created, T4 invokes a user-defined target specified in the $(BeforeTransform) property. You can assign this property and provide a custom target if you need to perform any actions before the templates are processed.

After executing the user-defined BeforeTransform target, T4 will use the initial candidate list of files to select those associated with the TextTemplatingFileGenerator custom tool to be transformed in a set of items called @(T4TransformInputs) and those associated with the TextTemplatingFilePreprocessor custom tool to be pre-processed in a set of items called @(T4PreprocessInputs). It is important to remember that template files are selected for processing based on their association with one of the T4’s custom tools; the file extension or build action have no effect in this process.

After determining the actual lists of templates, T4 transforms and pre-processes them. This is done by the MSBuild tasks called TransformTemplates and PreprocessTemplates implemented in Microsoft.TextTemplating.Build.Tasks.dll. These tasks use a custom T4 host implemented in Microsoft.VisualStudio.TextTemplating.Sdk.Host.10.0.dll.

In T4 architecture,  the host plays a very important role in the template transformation process. It provides the compilation and run-time environment for the code generation and determines how the included files are located, how the assembly references are resolved, how directive processors are selected and more. Each of the existing T4 hosts is implemented and configured differently, which can make them incompatible with templates that take advantage of the unique functionality of a particular host. For example, T4 templates in ASP.NET MVC and T4 Toolbox rely on the unique features of the MVC and Visual Studio hosts respectively. They are currently incompatible with the MSBuild host described here.

Even templates that don’t have hard-coded dependencies on a particular host will often require additional steps to configure the transformation environment before they can be processed by the MSBuild host. Detailed description of the configuration options is available later in this article.

After transforming and preprocessing templates, T4 invokes a second user-defined target specified in the $(AfterTransform) property. You can assign this variable and provide a custom target if you need to perform any actions when the templates are transformed but before the build starts.

Project and Source Control Integration

Unlike the standard Visual Studio host of T4, the MSBuild host described here does not integrate generated files with Visual Studio projects or source control. In particular, the generated files are not added to the project and source control automatically; the regenerated files are not checked out from source control automatically. This integration functionality relies on services provided by Visual Studio, which is not available in the MSBuild host.

Luckily, a limited awareness of source control exists in the MSBuild host of T4. By default, it will issue a warning for each read-only output file that could not be regenerated and an error, making sure that build will fail if one or more files could not be regenerated.

In order to resolve these errors, you can either locate and check out all required files manually, or transform all templates from the toolbar in Solution Explorer, which will process them using the Visual Studio host and check out all files automatically. Once the files have been regenerated, you will typically want to check them back in source control.

You can also instruct T4 to automatically overwrite read-only files during code generation by setting the $(OverwriteReadOnlyOutputFiles) property to true.

<PropertyGroup>
  <TransformOnBuild>true</TransformOnBuild>
  <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

This setting eliminates build errors, but introduces discrepancies between the code checked in the source control repository and the actual code compiled during the build. With this approach you can no longer rely on the source control repository alone to recreate a particular labeled build. If you want to debug or troubleshoot a particular build of the application later, you will have to save the complete source code in addition to the binary and symbol files produced by each build. This is necessary for all but trivial scenarios, and especially for packaged commercial software products and enterprise applications.

Configuring transformation environment

MSBuild functionality of T4 relies on a new engine host, which is different from both the default host used by the T4 custom tools in Visual Studio and the command line host used by TextTransform.exe. It relies on MSBuild items and properties to configure normal settings such as include search path, directive processors and assembly references, as well as settings unique to the MSBuild host.

$(IncludeFolders) property

Specifies a coma-separated list of directories that T4 will search to resolve files referenced by include directives. This property is empty by default.

<PropertyGroup>
  <IncludeFolders>$(MSBuildProjectDirectory)\Include</IncludeFolders>
</PropertyGroup>

$(IncludeFolders) property is an equivalent of the –I parameter of the command-line host and the HKLM\Software\Microsoft\VisualStudio\10.0\TextTemplating\IncludeFolders registry setting of the Visual Studio host of T4.

@(T4ReferencePath) items

Specify individual folders where T4 will search to resolve assemblies referenced by assembly directives and custom directive processors. This item list is empty by default.

<ItemGroup>
  <T4ReferencePath Include="$(VsInstallDir)PublicAssemblies\" />
</ItemGroup>

@(T4ReferencePath) items are an equivalent of the –P parameter of the command-line host and have no direct equivalent in the Visual Studio host of T4, which uses global assembly cache, assemblies referenced by the project and some hard-coded search paths.

@(DirectiveProcessor) items

Specify definitions of the directive processors T4 will use when processing custom directives. This item list is empty by default.

<ItemGroup>
  <DirectiveProcessor Include="T4Toolbox.XsdProcessor" >
    <Class>T4Toolbox.XsdProcessor</Class>
    <CodeBase>C:\Program Files (x86)\T4 Toolbox\Bin\T4Toolbox.10.0.dll</CodeBase>
  </DirectiveProcessor>
</ItemGroup>

Assembly location can be specified using either CodeBase or Assembly metadata item which allows you to reference the assembly from disk or from global assembly cache respectively.

<ItemGroup>
  <DirectiveProcessor Include="T4Toolbox.XsdProcessor" >
    <Class>T4Toolbox.XsdProcessor</Class>
    <Assembly>T4Toolbox.10.0, Version=10.3.7.1, Culture=neutral, PublicKeyToken=7e313accbcce84dc</Assembly>
  </DirectiveProcessor>
</ItemGroup>

@(DirectiveProcessor) items are an equivalent of the –db option of the command-line host and the HKLM\Software\Microsoft\VisualStudio\10.0\TextTemplating\DirectiveProcessors registry setting of the Visual Studio host of T4.

@(T4ParameterValues) items

Specify parameters that custom directive processors and templates themselves can query using ResolveParameterValue method. This item list is empty by default.

<ItemGroup>
  <T4ParameterValues Include="ParameterName">
    <Value>ParameterValue</Value>
  </T4ParameterValues>
</ItemGroup>

@(T4ParameterValues) items are an equivalent of the –a option of the command-line host and have no direct equivalent in the Visual Studio host of T4.

.OutputFilePath metadata

Specifies the directory where template’s output file will be generated. This metadata item is empty by default.

<ItemGroup>
  <None Include="Template.tt">
    <Generator>TextTemplatingFileGenerator</Generator>
    <OutputFilePath>$(IntermediateOutputPath)</OutputFilePath>
    <LastGenOutput>Template.cs</LastGenOutput>
  </None>
</ItemGroup>

By default, T4 will place generated output file in the same directory with the template file. You can set this property to redirect generated output files to a different directory during build-time code generation. This property has no effect on design-time code generation performed by the TextTemplatingFileGenerator or TextTemplatingFilePreprocessor when the template file is saved in Visual Studio editor. Setting this property will result in different behavior in code generation at design time vs. build time.

.OutputFilePath metadata is an equivalent of the –out option of the command-line host and has no direct equivalent in the Visual Studio host of T4.

.OutputFileName metadata

Specifies the name of the generated output file. This metadata item is empty by default.

<ItemGroup>
  <None Include="Template.tt">
    <Generator>TextTemplatingFileGenerator</Generator>
    <OutputFileName>Generated.cs</OutputFileName>
    <LastGenOutput>Template.cs</LastGenOutput>
  </None>
</ItemGroup>

By default, T4 will name generated output file with the name of the template file and the extension specified in the output directive in the template. You can set this property to change the default file name during build-time code generation. This property has no effect on design-time code generation performed by the TextTemplatingFileGenerator or TextTemplatingFilePreprocessor when the template file is saved in Visual Studio editor. Setting this property will result in different behavior in code generation at design time vs. build time.

.OutputFileName metadata is an equivalent of the –out option of the command-line host and has no direct equivalent in the Visual Studio host of T4.

$(IncludeDslT4Settings) property

Determines whether DSL-specific settings should be turned on. This property can be set to true or false and has a default value of false.

<PropertyGroup>
  <IncludeDslT4Settings>true</IncludeDslT4Settings>
</PropertyGroup>

This is a convenience property that configures various settings required for performing build-time template transformation in DSL projects.

Controlling transformation process

This section lists the various configuration settings that can be used to control the T4 template transformation process in MSBuild project files.

$(TransformOnBuild) property

Determines whether templates will be transformed at build-time automatically. This property can be set to true or false and has a default value of false. When $(TransformOnBuild) is false, templates will be transformed at design-time in Visual Studio and can also be transformed by calling MSBuild explicitly.

<PropertyGroup>
  <TransformOnBuild>true</TransformOnBuild>
</PropertyGroup>
$(TransformOutOfDateOnly) property

Controls incremental template transformation and indicates whether only out of date or all templates should be processed. This property can be set to true or false and has a default value of true.

<PropertyGroup>
  <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

An out-of-date file is one where any of the input files used to generated the file were modified more recently than the file itself. The input files are the included template files and the files referenced by custom directive processors. In addition, a file that contains only “ErrorGeneratingOutput” written to it when the last transformation failed is also treated as being out of date.

T4 relies on the file tracking feature in MSBuild by logging all of the file read / write operations as they occur when generating an output file. If the tracking logs do not exist for a project, T4 assumes that the template is out of date and transforms it.

$(TrackFileAccess) property

Determines whether T4 will log file read / write operations to allow subsequent incremental template transformations. This property can be set to true or false and has a default value of true.

<PropertyGroup>
  <TrackFileAccess>false</TrackFileAccess>
</PropertyGroup>

If you don’t rely on incremental template transformations, you may want to set this property to false to reduce the amount of space taken by the log files in the intermediate output directory (obj\Debug).

$(OverwriteReadOnlyOutputFiles) property

Indicates whether read-only output files will be overwritten during template transformation. This property can be set to true or false and has a default value of false.

<PropertyGroup>
  <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
</PropertyGroup>

When $(OverwriteReadOnlyOutputFiles) is false, T4 issues a warning for each output file that could not be regenerated because it is read-only and the build will fail. When $(OverwriteReadOnlyOutputFiles) is true, T4 will overwrite read-only files and report a warning for each overwritten file. These warnings are not considered to be compiler warnings for the purpose of the “Treat warnings as errors” project setting.

$(BeforeTransform) property

Specifies a user-defined MSBuild target that will be executed before template transformation. This property is empty by default.

<PropertyGroup>
  <TransformOnBuild>true</TransformOnBuild>
  <BeforeTransform>OnBeforeTransform</BeforeTransform>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
<Target Name="OnBeforeTransform">
  <Message Text="This executes before templates are transformed" Importance="high"/>
</Target>
$(AfterTransform) property

Specifies a user-defined MSBuild target that will be executed before template transformation. This property is empty by default.

<PropertyGroup>
  <TransformOnBuild>true</TransformOnBuild>
  <AfterTransform>OnAfterTransform</AfterTransform>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />
<Target Name="OnAfterTransform">
  <Message Text="This executes after templates are transformed" Importance="high"/>
</Target>
@(GeneratedFiles) items

Are produced by by the TransformTemplates and PreprocessTemplates to indicate output files that were successfully generated. @(GeneratedFiles) have .ReadOnlyFileOverwritten metadata item set to true when $(OverwriteReadOnlyOutputFiles) property is set to true and a particular read-only output file was overwritten during code generation. @(GeneratedFiles) items can be used in the user-defined AfterTransform target.

@(NonGeneratedFiles) items

Are produced by by the TransformTemplates and PreprocessTemplates to indicate output files that could not be regenerated. The list of @(NonGeneratedFiles) can be examined in the user-defined AfterTransform target.

Transforming templates by calling MSBuild explicitly

In addition to automatically transforming templates at build time, T4 provides two targets you can call explicitly to transform or preprocess templates in a particular project by invoking MSBuild from command line.

TransformAll target

Calling the TransformAll target will transform all files associated with TextTemplatingFileGenerator and TextTemplatingFilePreprocessor in the specified project. It is an equivalent of setting $(TransformOnBuild) to true and performing template transformation at build time.

Syntax
msbuild t4msbuild.csproj /t:TransformAll
Sample Output

image_thumb14[3]

Transform target

Transform target allows you to specify which file or files have to be transformed. It expects you to provide a value for TransformFile property, which accepts individual file names as well as MSBuild wildcards.

Syntax
msbuild t4msbuild.csproj /t:Transform /p:TransformFile=*.tt
Sample Output

Conclusion

Visual Studio 2010 introduced a new capability based on MSBuild extensions for transforming and preprocessing text templates at build time. The new capability comes with a set of distinct advantages and drawbacks. Compared to the existing command line tool, TextTransform, it makes implementation and maintenance of build-time template transformation easier. However, compared to the existing Visual Studio tools, it does not support project and source control integration. The MSBuild extensions also rely on a brand-new T4 engine host, with a unique compilation and run-time environment for text templates. Templates that take advantage of specific capabilities provided by a particular host (such as ASP.NET MVC and T4 Toolbox templates) are not be compatible with the new MSBuild host. Templates designed to be host-agnostic, may require you to configure the MSBuild host before they can be processed correctly. In particular, locations of the included files, .NET assemblies and definitions of custom directive processors have to be supplied explicitly.

Download


Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

[…] Understanding T4: MSBuild Integration (Oleg Sych) […]

Excellent write-up, thanks!

We just set up TFS 2010 at work, and are faced with an interesting problem. If you have any thoughts on it, we would appreciate the input.

We have a solution that has 3 web applications and a ’shared’ control library project (ascx + server controls). the old way was to do a pre-build task in every web project that copies the controls into an empty directory in the web project.

Going with TFS 2010 that didn’t seem to work - so we made an ‘include’ .targets file in the solution (it enumerates all the files in the control library), and each web .csproj references. That does work, but now we have to maintain that .targets file.
I was looking into T4 and trying to generate the file, but after reading some of MSDN and your stuff, i’m thinking that what would work in VS (with T4 Toolbox and Modeling + Vis SDK) won’t work so well with TFS.

Is there any advice you might have?

Pavel,

There are many different ways to address this problem, with T4 or without it. I would need to learn more about your situation before I can make a recommendation. Please contact me privately if you are interested in my assistance.

Oleg

Hello Oleg,

Firstly thanks a lot for your great T4-blog and very interesting findings.

I habe a question to you. T4 seems to be a great technology to be used for @development of development tools@, but can it be used for industial purposes, say for mass reports generation, extensive logging or for generation of mail bodies.

Can you imagine writing a custom directive processor supporting multithreading, which is used by 100 different clients, which generate 100000 text files each? Are there any limitations for applying T4 technology for industrial applications?

Is there any advice you might have?

[…] suffer from this problem, but it does not make developer’s life any easier. There is some build integration in VS 2010, but “in order to configure a Visual Studio project for build-time template […]

Another great article, it really helps in understanding how this feature works.

However, it seems to be missing support for custom code generators. I’ve been trying to get this to work, and it seems that creating a custom task to invoke the custom code generator is the only way to go… Do you have any ideas that could help in supporting this scenario?

Filipe,

I agree - the current implementation of MSBuild integration is rather limited. I would like to learn more about the scenario you have in mind. Can you post more details here or contact me privately?

Thanks,
Oleg

Hi Oleg,

After thinking about it, the custom code generator is not actually an issue. I’m able to generate code using the default tool with the command line (TextTransform.exe). With the lessons learned by making this work with the command line tool, I found out what needs to be done. The target “CreateT4ItemLists” must be redefined to consider the templates that have my code generator and not just the default ones.

Thanks,
Filipe

[…] new feature that has been introduced in Visual Studio 2010. I’ve been reading this in-depth analysis on this feature, and being the first version it’s obviously not without it’s […]

Hello again,

I’ve been thinking about the lack of source control integration in T4 MSBuild and just posted a possible solution to this issue.

http://lessisthenewmore.wordpress.com/2010/05/25/source-control-and-t4-msbuild-integration/

Let me know what you think about it.

Thanks.

Filipe,

The example you posted is a great starting point. I’m not sure you would want to check generated files in automatically in the AfterTransform target though. This operation is something I typically want a developer to perform after reviewing the changes in case there is a problem with the generated code.

Oleg

I’m guessing I’ve missed something fundamental, but i can’t get this to work. I created a new Project, added a hello world tt script, which also contains the current date time. Added the XML as defined in the “Configuring for build-time template transformation”, the effect of this is the output window doesn’t appear as you described, and the output file is not overwritten. I then added the OnBeforeTransform and OnAfterTransform messages, they trigger in the output window, but the .cs file isn’t overwritten? Do you have a sample hello world solution you could share which demonstrates the Build integration? I’m wondering if i’ve fundamentally misinterpretted what the build integration is capable of doing?

Hi Oleg,
I’ve managed to fix my problem, i’m not sure why it didn’t occur to me to try it earlier, but i just needed to set the TransformOutOfDateOnly property to false.
Thanks for your blog, it’s a wonderfully comprehensive resource.

Cannot make it work. I updated my project file and I got the following error:
“Running transformation: System.ArgumentNullException: Value cannot be null.
Parameter name: Could not obtain DTE from host”

I might miss something very important, but I don’t know what. Could you please publish your “t4msbuild” project so I could compare with my project and fix the problem.

Maxim

Hi Oleg

I am trying to use the MSBuild extentions however some of my templates use VS variables in reference assembly directive, i.e

This works fine is VS2010 but not in the msbuild host. Any suggestion how I can reference an assembly with a relative path and work in both the VS2010 host and the msbuild host.

thanks
Kendall

Hi Oleg,

First of all let me thank you for your extended article on the subject and your general contribution to the T4 community.
Now, I am facing the same problem as Maxim (see comment number 14) and get the following exception when the transformation is run from within my Visual Studio when the project builds:
Error 1 Running transformation: System.ArgumentNullException: Value cannot be null.
Parameter name: Could not obtain DTE from host
at Microsoft.VisualStudio.TextTemplating41FDF5B3010E4E4C9D7658B293ACAB45.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.VsEntityFrameworkTemplateFileManager..ctor(Object textTemplating) in c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude:line 1867
at Microsoft.VisualStudio.TextTemplating41FDF5B3010E4E4C9D7658B293ACAB45.GeneratedTextTransformation.EntityFrameworkTemplateFileManager.Create(Object textTransformation) in c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude:line 1702
at Microsoft.VisualStudio.TextTemplating41FDF5B3010E4E4C9D7658B293ACAB45.GeneratedTextTransformation.TransformText() in c:\Projects\Afda\Main\Afda\Afda.DAL\AfdaModel.Context.tt:line 288
at Microsoft.VisualStudio.TextTemplating.TransformationRunner.RunTransformation(TemplateProcessingSession session, String source, ITextTemplatingEngineHost host, String& result). Line=0, Column=0 Afda.DAL

All files have been previously checked out but it doesn’t help.

Any support would be appreciated.

Thank you in advance, kind regards,
Olivier

@Maxim and Olivier,

You can’t get the DTE object when running the transformation outside the VS Host. This error occurs, for example when running the transformation within a Team Build (the MSBuild Host does not “know” the DTE object).
I think this should not happen in Olivier’s case, but I’ll have to try it first.

[…] Understanding T4: MSBuild Integration build, msbuild, T4, template, VS2010 Hits for this post: 1 . Address: http://mariusbancila.ro/blog/2011/05/04/generate-output-from-t4-at-build-time/ « Finding Installed Applications with VC++ Trackbackno comment untill now […]

Hi, i have a custom tool and i would like to integrate with msbuild. I already read that isn’t supported but anyone have an idea to resolve this?

Oleg, or Filipe,

Regarding the error found by Maxim ( Could not obtain DTE from host) — how in MSBUILD do we get the host ?
Below is a full list of the MSBuild errors I see .
Thanks, Peter
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets(396,5): error : Running transformation: System.ArgumentNullException: Value cannot be null. [C:\xx.csproj]
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets(396,5): error : Parameter name: Could not obtain DTE from host [C:\xxx.csproj]

Hello

I am using diferent .tt files in a project but i want make the execution during TFS buil only on one of the .tt files.

I add the tags in de project file but i need to know how can i select only one .tt file. I use de msbuild command into a pre-build event, but a i prefer put the entry into the project file.

Using the msbuild command this is my .csproj file

false
false
true

If i put the TransformOnBuild = true all the .tt files are procesed, but in one of the files i receive the error (Could not obtain DTE from host) and i can´t find a solution, this is the reason to use a filter.

I follow your instruction but when I run my solution I got following error (I’m building inside VS). Could you help me? Thx

Running transformation: System.ArgumentNullException: Value cannot be null. Parameter name: Could not obtain DTE from host

Hi, thanks a lot for this article.
Unfortunately, after some painful hours, I failed to automate my filed generation.
I want to be able to generate my files from within the IDE (”Run Custom Tools”), and to automate the generation @ build in my build factory….
It seems that the underlyng “environment” when I start transformation from the IDE and from MSBUILD is not the same (Include path, referenced assemblies, etc..). Am I trying to do something impossible ?
Thanks for your help

[…] save a template file or Run Custom Tool from the Solution Explorer. Since then, T4 gained better MSBuild support and many developers want to perform code generation at build time or both build and design time. In […]

Hi Oleg,

Thanks very much for putting this together, this is great help!

I am using preprocessed templates and I am having one difference between using this build task versus using Visual Studio. Visual Studio supports a custom namespace for each template file using the CustomToolNamespace property.

Looking at the Microsoft.TextTemplating.targets file, it seems that all .tt files are generated using a single namespace, which will either be the project’s root namespace or the value of the PreprocessTemplateDefaultNamespace property, if provided.

Setting that property in my .csproj is working ok for me now, because all my stuff is in a single common namespace anyway. But ideally it would be good to have this per file. Can you help?