Elton Stoneman

  Home  |   Contact  |   Syndication    |   Login
  80 Posts | 0 Stories | 111 Comments | 0 Trackbacks

News

Archives

Post Categories

[Source: http://geekswithblogs.net/EltonStoneman]

I was looking for an MSBuild task which could execute a T4 template, replacing tags in the template with the value of properties or item groups from the build - giving your T4 templates access to all the runtime values used in the build scripts. So you start with a T4 template like this:

<#@ template language="C#" #>

<#@ output extension=".txt" #>

<#@ assembly name="System.dll" #>

***START

Property value: StartDir= $(StartDir)

Item Group value: TextFiles = @(TextFiles)

***END

 

- execute it through a call to ExecuteT4Template in your build target:

<PropertyGroup>

<StartDir>C:</StartDir>

</PropertyGroup>

 

<ItemGroup>

<TextFiles Include="$(BuildOutputDir)\*.txt"/>

</ItemGroup>

 

<Target Name="ExecuteTemplate">

<ExecuteT4Template TemplatePath="T4Sample.tt" OutputPath="c:\T4SampleOutput.txt"/>

</Target>

 

- and it produces the following output:

***START

Property value: StartDir= C:

Item Group value: TextFiles = \zeros.txt

***END


There wasn't one that I could find so I put a simple one together. A couple of fiddly things worth noting if you do something similar:

  1. the project's property values are not exposed to the executing task in an accessible way, so you have to reflect around BuildEngine to get hold of the executing project;
  2. if you don't want to write an ITextTemplatingEngineHost or rely on a GAX or other host, you'll end up shelling out to TextTransform.exe (as I have).

Full source for the task is here: ExecuteT4Template.cs (note this uses version 1.1 of the TextTransform tool).

A couple of things to note: this task will update all instances of property and item tags in the template - $(propertyName) or @(itemGroupName) (it's not clever enough to deal with %(itemGroupName.ValueName))- with the value from MSBuild, if the named property/item group exists in the project. Potentially you may want to leave certain tags in place in the template, in which case you'll need to ensure there are no matching properties in the build, or extend the task to take a list of names to ignore.

Also, if you're using a value in your script which is the output from another task, then the task which produces the output must be in a separate target which completes before the call to ExecuteT4Template. MSBuild seems only to store properties/item groups from task outputs when targets are completed, so if the output is created in the same target as the T4 task, the property won't be registered and the tag in the template won't be replaced.

I have a couple of other tasks which all relate to deploying BizTalk and ESB Service Providers, so I'll add them to the ESBSimpleSamples CodePlex project along with this one.

posted on Friday, July 25, 2008 1:54 PM

Feedback

# re: An MSBuild task to execute T4 templates 7/27/2008 3:04 PM Oleg Sych
Elton,

This is a great idea. Not only does it allow you to reference project properties and items, it also enables using T4 templates in Visual Studio projects that don't support custom tools. Database projects in Visual Studio DBPro Edition could greatly benefit from code generation but don't support custom tools.

Is it possible to access Visual Studio services, i.e. extensibility APIs from a custom MSBuild task when it is running in Visual Studio? I'm asking is because most of my templates rely on extensibility APIs to add output files to the project. How would that work when the template is running in MSBuild?

Oleg

# re: An MSBuild task to execute T4 templates 7/29/2008 2:32 PM Elton
Good question, Oleg. The APIs are all available to GAX actions, so running the template through the GAX host rather than the command line may make VS available to the templates. I'll have a look and post an update.

# re: An MSBuild task to execute T4 templates 10/4/2008 9:17 AM Elton
Note, the task has been updated now to run under MSBuild 2.0 and 3.5: http://geekswithblogs.net/EltonStoneman/archive/2008/10/04/executet4template-msbuild-task-updated.aspx

# re: An MSBuild task to execute T4 templates 12/7/2008 1:20 PM Landing Page Templates
This is indeed a great idea. I just love it.

# re: An MSBuild task to execute T4 templates 1/5/2009 9:56 PM ride on mowers
Thanks for this scripting tutorial.

# re: An MSBuild task to execute T4 templates 4/9/2009 3:17 PM jeremy
Your color scheme on the website makes it almost impossible to read your code snippets.

# re: An MSBuild task to execute T4 templates 4/9/2009 3:53 PM Elton
Fair point Jeremy, I was experimenting with a new skin but the classic version is easier on the eyes. Back to the way it was now.

# re: An MSBuild task to execute T4 templates 5/15/2009 8:16 PM Bowling Balls for Sale
Great work. It is exactly what i was looking for. it gets right to the poing. Excellent! Cheap Bowling Balls

# re: An MSBuild task to execute T4 templates 5/15/2009 8:19 PM Youth Baseball Bats For Sale
That is a really great work around to a bit of a sticky problem. And such a simple solution as well. Thank you very much for the information. Great work putting this together. Cheap Youth Baseball Bats

# re: An MSBuild task to execute T4 templates 6/26/2009 8:06 PM Ogre
Seems that I'm unable to call this task from a .targets file?

D:\Dev\MediaBrowser\OgreBranch\MediaBrowser.targets(235,9): error MSB4018: System.Exception: ProjectHelper: exception retrieving executing project: Object reference not set to an instance of an object.
D:\Dev\MediaBrowser\OgreBranch\MediaBrowser.targets(235,9): error MSB4018: at Sixeyed.MSBuild.Project.ProjectFactory.GetProject(ITask executingTask) in D:\Dev\MediaBrowser\OgreBranch\BuildTasks\Sixeyed.MSBuild\Project\ProjectFactory.cs:line 40

# re: An MSBuild task to execute T4 templates 8/16/2009 6:37 AM registry cleaners station
I didn't realize how simple the code for the template is. You did a good job with this.

# re: An MSBuild task to execute T4 templates 8/21/2009 3:13 AM folding chairs
I'm developing a new skin for my main site. I think I could get some use for your algorithm in mine. You are a very skilled programmer. Kudo.

# re: An MSBuild task to execute T4 templates 8/26/2009 3:00 AM kids loft beds
I agree with you. It was so easy to follow.

# re: An MSBuild task to execute T4 templates 8/26/2009 3:04 AM typy bukmacherskie
Such an helpful resource, thanks for that kind of info, now i can fix my bug ! Really great share !

I enjoy T4 templates !

# re: An MSBuild task to execute T4 templates 9/4/2009 4:46 AM Deresen
I'm using this very usefull msbuild task. But have one question.
I would like to use the properties inside my template, something like this:

<# var myProp = $(StartDir) #>
MyProperty: <#= myProp #>

Is this possible? Because I can't get it working.

# re: An MSBuild task to execute T4 templates 9/26/2009 2:51 AM external hard drive
Wow, If I only understood this code.

# re: An MSBuild task to execute T4 templates 10/20/2009 11:40 AM closet organizers sytems
The build target series of codes is what I'm missing before. I never thought it could be this simple.

# re: An MSBuild task to execute T4 templates 10/31/2009 5:29 AM Baby Modeling
Haha, this code is really sneaky - I love it. Thanks for the idea, I'm definitely going to try it out.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: