<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Aaron Hallberg</title><subtitle type="html">Team Build (Build Automation) - Visual Studio North Carolina</subtitle><id>http://blogs.msdn.com/aaronhallberg/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/aaronhallberg/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2008-02-12T10:04:00Z</updated><entry><title>Writing Custom Activities for TFS Build 2010 (Beta 1)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2009/06/01/writing-custom-activities-for-tfs-build-2010-beta-1.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2009/06/01/writing-custom-activities-for-tfs-build-2010-beta-1.aspx</id><published>2009-06-01T14:49:30Z</published><updated>2009-06-01T14:49:30Z</updated><content type="html">&lt;p&gt;With &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;TFS Build 2010 (Beta 1)&lt;/a&gt;, we've changed the build orchestration language from MSBuild to Windows Workflow Foundation (WF).&amp;#160; As such, you now have a new option for adding custom logic to your build proces - custom WF activities.&amp;#160; I've gotten a couple of requests for a blog post with an example, best practices, and so forth, so here goes.&lt;/p&gt;  &lt;p&gt;There are four ways (that I know of, at least) to author a custom WF activity - using the WF Designer / XML Editor and &lt;em&gt;composing&lt;/em&gt; your custom activity in XAML; &lt;em&gt;composing &lt;/em&gt;your custom activity in code; writing a custom &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.codeactivity(VS.100).aspx"&gt;CodeActivity&lt;/a&gt;&lt;/em&gt;; or writing a custom &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.nativeactivity(VS.100).aspx"&gt;NativeActivity&lt;/a&gt;&lt;/em&gt;.&amp;#160; This list is more or lest organized by degree of difficulty, and more or less by preference as well.&amp;#160; &lt;/p&gt;  &lt;p&gt;The first two approaches involve building a new activity up from existing activities - when possible, this is a good strategy, since it has several advantages over writing custom code to do your work:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Composed activities obviously re-use code to a high degree, which is always a good idea - why reinvent the wheel if you don't have to? &lt;/li&gt;    &lt;li&gt;Composed activities are by their nature &lt;em&gt;cancellable &lt;/em&gt;by the workflow runtime, meaning that builds running your custom activity will be easy to stop cleanly. &lt;/li&gt;    &lt;li&gt;Composed activities can participate in workflow tracking, meaning that their internal progress can be easily tracked as they execute.&amp;#160; (If you don't &lt;em&gt;want&lt;/em&gt; their progress to be tracked when running in a build, you can turn this behavior off using Microsoft.TeamFoundation.Build.Workflow.Tracking.ActivityTrackingAttribute.) &lt;/li&gt;    &lt;li&gt;It's comparatively easy, at least once you get the hang of it. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I'll be tackling these approaches in this post, and the &lt;em&gt;CodeActivity&lt;/em&gt; and &lt;em&gt;NativeActivity&lt;/em&gt; approaches in a subsequent post.&amp;#160; The activity I'll be writing takes in a server path to a script file and a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.workspace.aspx"&gt;Workspace&lt;/a&gt; object (along with a couple of other optional parameters), executes the script, and returns the exit code.&amp;#160; The assumption, then, is that this activity will be used in a build process at some point &lt;em&gt;after&lt;/em&gt; the workspace for the build has been set up and &lt;em&gt;after&lt;/em&gt; that workspace has been synched.&amp;#160; Note that a big difference between MSBuild and WF is that WF can hand actual objects around between activities, as opposed to MSBuild which basically just hands strings around.&amp;#160; &lt;/p&gt;  &lt;p&gt;To write my activity, I created a new WF &lt;em&gt;ActivityLibrary&lt;/em&gt; project, added references to Microsoft.TeamFoundation.Build.Client, Microsoft.TeamFoundation.Build.Common, Microsoft.TeamFoundation.Build.Workflow, Microsoft.TeamFoundation.VersionControl.Client, and Microsoft.TeamFoundation.VersionControl.Common.&amp;#160; I then added the various arguments I wanted my activity to have using the &lt;em&gt;Arguments &lt;/em&gt;flyout in the WF designer, dragged and dropped a Sequence activity and the two TFS Build activities I needed, set the appropriate properties, etc.&amp;#160; Here's what it looks like in the Beta 1 WF Designer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_2.jpg"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InvokeScript" src="http://blogs.msdn.com/blogfiles/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_thumb.jpg" width="235" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And here's the XAML:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Activity&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; mc&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Ignorable&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Class&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;ActivityLibrary1.InvokeScript&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;http://schemas.microsoft.com/netfx/2009/xaml/activities/design&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;__&lt;span style="color: rgb(255,0,0)"&gt;InvokeScript&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;clr-namespace:ActivityLibrary1;&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;mc&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;http://schemas.openxmlformats.org/markup-compatibility/2006&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;mtvc&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;http://schemas.microsoft.com/netfx/2009/xaml/activities&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;sad&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;clr-namespace:System.Activities.Debugger;assembly=System.Activities&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Members&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Property&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Arguments&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Type&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;p:InArgument(x:String)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Property&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Script&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Type&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;p:InArgument(x:String)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Property&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;WorkingDirectory&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Type&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;p:InArgument(x:String)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Property&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Workspace&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Type&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;p:InArgument(mtvc:Workspace)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Property&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;ExitCode&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Type&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;p:OutArgument(x:Int32)&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Members&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Sequence&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; DisplayName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Invoke Script From Source Control&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Sequence.Variables&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Variable&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;localScriptPath&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Sequence.Variables&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ConvertWorkspaceItem&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; DisplayName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Convert Server Path to Local Path&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Input&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[Script]&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Result&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[localScriptPath]&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Workspace&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[Workspace]&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Arguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[String.Format(&amp;amp;quot;/c &amp;amp;quot;&amp;amp;quot;{0}&amp;amp;quot;&amp;amp;quot; {1}&amp;amp;quot;, localScriptPath, Arguments)]&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; DisplayName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Invoke the Script&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; FileName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[&amp;amp;quot;cmd.exe&amp;amp;quot;]&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Result&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[ExitCode]&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; WorkingDirectory&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[WorkingDirectory]&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.BeforeExecute&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Variable&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;commandLine&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;WriteBuildMessage&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Message&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[commandLine]&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.BeforeExecute&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.ErrorDataReceived&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Variable&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;errorData&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;WriteBuildError&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Message&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[errorData]&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.ErrorDataReceived&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.OutputDataReceived&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Variable&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; x&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TypeArguments&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;x:String&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;outputData&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction.Argument&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;          &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;WriteBuildMessage&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Importance&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;Normal&amp;quot;&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt; Message&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&amp;quot;[outputData]&amp;quot; /&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ActivityAction&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess.OutputDataReceived&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;mtbwa&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;InvokeProcess&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Sequence&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;p&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Activity&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You might notice that the various &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.activityaction(VS.100).aspx"&gt;ActivityActions&lt;/a&gt; in the XAML (which handle writing the command-line and standard output to the build activity log as messages, and standard error as errors) are not present in the designer - we didn't get around to implementing a custom designer for the &lt;em&gt;InvokeProcess&lt;/em&gt; activity for Beta 1, so for this activity I had to &amp;quot;drop to XAML&amp;quot; and edit the XML directly.&amp;#160; Normally this shouldn't be required - for the most part you should be able to fully author your custom activities in the WF Designer.&amp;#160; When my activity library project is built, this XAML will be compiled into an activity named InvokeScript (the name comes from the x:Class attribute on the root).&lt;/p&gt;

&lt;p&gt;As mentioned above, activities can be composed either in xaml or in code.&amp;#160; To write a composed activity in code, you'll derive from &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.activity(VS.100).aspx"&gt;System.Activities.Activity&lt;/a&gt;, or &lt;a href="http://msdn.microsoft.com/en-us/library/dd466009(VS.100).aspx"&gt;System.Activities.Activity&amp;lt;T&amp;gt;&lt;/a&gt;, add whatever arguments and so forth you need, and then override the &lt;em&gt;CreateBody&lt;/em&gt; method to return your composed implementation.&amp;#160; Here's a second version of my InvokeScript activity, written in C# code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Activities;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Activities.Statements;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.ComponentModel;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.TeamFoundation.Build.Workflow.Activities;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.TeamFoundation.VersionControl.Client;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; ActivityLibrary1
{
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;sealed&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;InvokeScript2&lt;/span&gt; : Activity&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;Int32&lt;/span&gt;&amp;gt;
    {
        [Browsable(&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        [DefaultValue(&lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; Arguments { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }

        [Browsable(&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        [DefaultValue(&lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; Script { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }

        [Browsable(&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        [DefaultValue(&lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; WorkingDirectory { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }

        [Browsable(&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        [DefaultValue(&lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; InArgument&amp;lt;Workspace&amp;gt; Workspace { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }

        &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; WorkflowElement CreateBody()
        {
            Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; localScriptPath = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;();
            Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; commandLine = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;();
            Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; outputData = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;();
            Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt; errorData = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Variable&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;();

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Sequence
            {
                Variables = 
                {
                    localScriptPath
                },
                Activities =
                {
                    &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; ConvertWorkspaceItem
                    {
                        Input = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;.Script.Get(env)),
                        Workspace = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InArgument&amp;lt;Workspace&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;.Workspace.Get(env)),
                        Result = localScriptPath
                    },
                    &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InvokeProcess
                    {
                        FileName = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;cmd.exe&amp;quot;&lt;/span&gt;),
                        Arguments = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;/c \&amp;quot;{0}\&amp;quot; {1}&amp;quot;&lt;/span&gt;, localScriptPath.Get(env), Arguments.Get(env))),
                        WorkingDirectory = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;.WorkingDirectory.Get(env)),
                        Result = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; OutArgument&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;&amp;gt;(env =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;.Result.Get(env)),
                        BeforeExecute = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;
                        {
                            Argument = commandLine,
                            Handler = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; WriteBuildMessage
                            {
                                Message = commandLine
                            },
                        },
                        OutputDataReceived = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;
                        {
                            Argument = outputData,
                            Handler = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; WriteBuildMessage
                            {
                                Message = outputData
                            },
                        },
                        ErrorDataReceived = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt;&amp;gt;
                        {
                            Argument = errorData,
                            Handler = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; WriteBuildError
                            {
                                Message = errorData
                            },
                        },
                    },
                },
            };
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The primary difference between this version and the XAML version is that here I've elevated the single output argument (ExitCode) to the &lt;em&gt;return&lt;/em&gt; value of the activity - hence it derives from Activity&amp;lt;Int32&amp;gt;.&amp;#160; The metaphor for activities is methods and functions - when you have a single output, the standard practice is to elevate it to the return value rather than using an &lt;a href="http://msdn.microsoft.com/en-us/library/system.activities.outargument(VS.100).aspx"&gt;OutArgument&lt;/a&gt; (but this is not, so far as I know, possible when writing an activity in XAML).&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9678214" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author><category term="VSTS2010" scheme="http://blogs.msdn.com/aaronhallberg/archive/tags/VSTS2010/default.aspx" /></entry><entry><title>TargetsNotLogged Hotfix Available</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2009/01/30/targetsnotlogged-hotfix-available.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2009/01/30/targetsnotlogged-hotfix-available.aspx</id><published>2009-01-30T16:14:22Z</published><updated>2009-01-30T16:14:22Z</updated><content type="html">&lt;p&gt;I did a &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx"&gt;post&lt;/a&gt; a while back on a change in TFS Build SP1 which reduced build log noise by cutting out the build steps for project-to-project references (of the form &amp;quot;Project 'project' is building project 'dependent project' for target(s) 'GetNativePath'&amp;quot;, and so forth).&amp;#160; Unfortunately, as noted on the TFS Build &lt;a href="http://social.msdn.microsoft.com/forums/en-US/tfsbuild/thread/49106d4e-74ff-45fa-a744-6a21fa35e081/"&gt;forums&lt;/a&gt; and elsewhere, the fix in SP1 didn't actually fix the problem, at least not completely.&amp;#160; In particular, the mechanism we used to communicate the TargetsNotLogged property to our logger and thereby skip the logging of particular targets only worked the &lt;em&gt;first&lt;/em&gt; time a particular project-to-project reference was evaluated.&amp;#160; As such, if a project was referenced by 10 other projects the fix in SP1 would reduce the number of spurious build steps from 10*3 to 9*3 rather than removing them altogether.&lt;/p&gt;  &lt;p&gt;A hotfix is finally available that will address the remaining parts of the problem - it can be downloaded &lt;a href="http://code.msdn.microsoft.com/KB958845"&gt;here&lt;/a&gt;.&amp;#160; Note that this hotfix assumes that you have already installed SP1 on your build machine, so make sure to install SP1 and &lt;em&gt;then&lt;/em&gt; the hotfix if you are currently running TFS Build 2008 RTM bits.&amp;#160; After this hotfix is applied you should, by default, never see another project-to-project reference build step - I've heard reports from some customers of this reducing their total number of build steps from over 3000 to under 200, so in some cases this can have a &lt;em&gt;dramatic &lt;/em&gt;effect on build time (each of those build steps corresponds to a server call made during the build).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9384921" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Calling Custom Targets in Team Build, Part 3</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/12/30/calling-custom-targets-in-team-build-part-3.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/12/30/calling-custom-targets-in-team-build-part-3.aspx</id><published>2008-12-30T21:13:15Z</published><updated>2008-12-30T21:13:15Z</updated><content type="html">&lt;p&gt;I've done a couple of posts now on calling custom targets during a Team Build build - &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/07/calling-custom-targets-within-team-build.aspx"&gt;this one&lt;/a&gt; focused on calling custom targets in the solution/project being built, and &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2008/02/08/calling-custom-targets-within-team-build-part-2.aspx"&gt;this one&lt;/a&gt; focused on calling custom targets in your TfsBuild.proj file itself before/after the compilation of individual solutions or configurations.&amp;#160; In the past week I've gotten two questions on whether one can call custom targets before/after the compilation of individual &lt;em&gt;projects&lt;/em&gt; within a solution.&amp;#160; That is, whether Microsoft.TeamFoundation.Build.targets supports Before/AfterCompileProject targets in the same way it supports Before/AfterCompileConfiguration and Before/AfterCompileSolution ones.&lt;/p&gt;  &lt;p&gt;The short answer is that this is not really supported in Team Build 2008 (or 2005, for that matter), since by the time your solutions are getting built we have essentially ceded control to MSBuild.&amp;#160; There are three potential methods (that I could think of) for doing this sort of thing:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;You could specify the individual projects, rather than the solution that contains them, in the SolutionToBuild item group in your TfsBuild.proj file and then just use the Before/AfterCompileSolution targets to execute your custom logic.&amp;#160; This is only appropriate if your solutions are simple containers for your projects - in particular, if you don't have build order logic and/or project-to-project references in your solution that you would need to re-implement in your TfsBuild.proj file.&lt;/li&gt;    &lt;li&gt;You could use a custom MSBuild &amp;quot;traversal&amp;quot; project in place of your solution, and insert your custom logic into this traversal project before/after the individual projects are compiled.&amp;#160; The simplest thing here would be to start with the the project that MSBuild generates from your solution - in MSBuild 3.5 this project will be written to disk as a *.sln.cache file if you build your solution from the command-line.&amp;#160; The disadvantage to this approach is that you then have two files to maintain in parallel - your solution and your custom traversal project.&amp;#160; One possible workaround here would be to write a custom MSBuild task to generate this traversal project automatically as part of the build.&amp;#160; If anybody is adventurous enough to attempt this task and generous enough to share, please let me know and I'd be happy to post your efforts in a follow up.&amp;#160; &lt;/li&gt;    &lt;li&gt;Finally, you could put the before/after compile logic into the individual projects themselves, either directly or via in imported *.targets file.&amp;#160; Individual .NET projects have their own Before/AfterBuild extensibility targets that could be utilized for this purpose.&amp;#160; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This last option strikes me as the best one when including simplicity in the calculation...&amp;#160; The targets file would look something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;xml&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;version&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;encoding&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;

  &amp;lt;!--&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt; Only execute this custom logic when the project is building under Team Build. &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;--&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;AfterBuild&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Condition&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; '$(TeamBuildConstants)' == '_TEAM_BUILD_' &lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;!--&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt; Put your custom logic here. &lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;--&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
  
&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;You would then check this targets file in alongside your TfsBuild.proj file and import it into your individual projects after the import of Microsoft.Common.targets using a relative path.&amp;#160; For example, the end of a *.csproj file might look like:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Import&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(MSBuildToolsPath)\Microsoft.CSharp.targets&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Import&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;..\..\TeamBuildTypes\SomeDefinition\AfterCompileProject.targets&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;/&amp;gt;
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9257620" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>The CompilationOutputs Item Group</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/08/08/the-compilationoutputs-item-group.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/08/08/the-compilationoutputs-item-group.aspx</id><published>2008-08-08T17:49:29Z</published><updated>2008-08-08T17:49:29Z</updated><content type="html">&lt;p&gt;I've mentioned the CompilationOutputs item group we added in TFS 2008 before in passing (see this &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/07/12/team-build-devenv-task.aspx"&gt;post&lt;/a&gt;, for example), but never given it the attention it deserves...&amp;#160; This item group is built up over the course of the Compile / CompileConfiguration / CompileSolution targets, and by the end of the build it contains the full list of outputs generated by all the items in your SolutionToBuild item group.&amp;#160; Furthermore, it includes metadata that allows you to distinguish the outputs for each platform/configuration pair and for each individual solution.&amp;#160; For example, given solutions Foo.sln and Bar.sln and configurations x86|Debug and x86|Retail, the following target:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;AfterCompile&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Message&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Text&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;%(CompilationOutputs.Solution) built %(Identity) for %(Platform)|%(Configuration).&lt;/span&gt;&amp;quot; /&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt; &lt;/span&gt;
&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;...might produce the following output:&lt;/p&gt;

&lt;pre class="code"&gt;  C:\BuildLocation\TeamProject\Definition\Sources\Foo.sln built C:\BuildLocation\TeamProject\Definition\Binaries\x86\Debug\Foo.exe for x86|Debug.
  C:\BuildLocation\TeamProject\Definition\Sources\Bar.sln built C:\BuildLocation\TeamProject\Definition\Binaries\x86\Debug\Bar.exe for x86|Debug.
  C:\BuildLocation\TeamProject\Definition\Sources\Foo.sln built C:\BuildLocation\TeamProject\Definition\Binaries\x86\Release\Foo.exe for x86|Release.
  C:\BuildLocation\TeamProject\Definition\Sources\Bar.sln built C:\BuildLocation\TeamProject\Definition\Binaries\x86\Release\Bar.exe for x86|Release.&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Of course, producing that output is not particularly exciting.&amp;#160; It is easy to imagine lots of other cool things that can be done with this information, however, including copying all build outputs to the drop location without putting them in the default build location (where they all end up in a single folder).&amp;#160; I'm sure users of Team Build will come up with lots of other creative uses for this item group as well.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8843914" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>A Minimal TFSBuild.Proj File</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/07/28/a-minimal-tfsbuild-proj-file.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/07/28/a-minimal-tfsbuild-proj-file.aspx</id><published>2008-07-28T14:31:29Z</published><updated>2008-07-28T14:31:29Z</updated><content type="html">&lt;p&gt;A fair number of people seem to want to use Team Build to kick off their own pre-existing build scripts that have nothing in common with the process defined in Microsoft.TeamFoundation.Build.targets.&amp;#160; While we don't typically &lt;em&gt;encourage&lt;/em&gt; this, enough people want to do it that I figured I should finally post an example.&amp;#160; So - the minimal tfsbuild.proj file that will kick off your custom build script would look something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;xml&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;version&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;encoding&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;xmlns&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;ToolsVersion&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;3.5&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;EndToEndIteration&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Exec&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Command&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;SomeScript.cmd&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Project&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Of course, most of the Team Build goodness comes from executing the standard targets while having our logger attached, so this approach will not generate a lot of information - no build steps will show up in the build report within VS, it won't keep track of errors/warnings, no data will be pushed to the warehouse (and thus reporting across builds will not work), and so forth.&lt;/p&gt;

&lt;p&gt;If you can abstract your custom build script down to the compilation portion, and let the standard build process handle the Get, the Label, etc. you'll be in better shape.&amp;#160; To do this, just override the BeforeCompile target and execute your custom script there, leaving the rest of the TfsBuild.proj file (especially the &lt;em&gt;import&lt;/em&gt; of Microsoft.TeamFoundation.Build.targets) alone.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8784395" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Associating changesets and Work Items Since the Last Successful Build</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/07/16/associating-changesets-and-work-items-since-the-last-successful-build.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/07/16/associating-changesets-and-work-items-since-the-last-successful-build.aspx</id><published>2008-07-16T13:40:32Z</published><updated>2008-07-16T13:40:32Z</updated><content type="html">&lt;p&gt;We got a forum post the other day on whether changesets and work items could be associated since the last &lt;em&gt;Successful&lt;/em&gt; build.&amp;#160; Some of you may be thinking &amp;quot;Isn't that how it already works?&amp;quot;&amp;#160; Actually, it's not &lt;em&gt;quite&lt;/em&gt; how it works.&amp;#160; Changesets and Work Items are, by default, associated since the last &amp;quot;good&amp;quot; build, where &amp;quot;good&amp;quot; means compilation and tests succeeded, but something else may have gone wrong.&amp;#160; That is, the last &amp;quot;good&amp;quot; build may well be marked &lt;em&gt;Partially&lt;/em&gt; &lt;em&gt;Succeeded&lt;/em&gt; and not &lt;em&gt;Succeeded&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;I started responding to the forum post, and then figured it would make a good blog post instead.&amp;#160; (Of course, I've posted a link to this post in the forums...)&lt;/p&gt;  &lt;p&gt;So - to modify the default behavior and associate changesets and work items only since the last &lt;em&gt;successful&lt;/em&gt; build, you'll need to do three things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Skip the default logic to associate changesets and work items.&amp;#160; This is pretty simple - just set the SkipGetChangesetsAndUpdateWorkItems property to true. &lt;/li&gt;    &lt;li&gt;Write a custom task to &lt;em&gt;find&lt;/em&gt; the last successful build and return its label. &lt;/li&gt;    &lt;li&gt;Call this custom task and then call the GenCheckinNotesUpdateWorkItems task with its output. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Lucky for you, I've already written the custom task (or at least a simple version of it).&amp;#160; Here is the source for it:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.Build.Framework;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.TeamFoundation.Client;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.TeamFoundation.Build.Client;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; BlogProjects
{
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;GetLastSuccessfulBuildLabel&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;ITask
&lt;/span&gt;    {
&lt;span style="color: rgb(0,0,255)"&gt;        #region&lt;/span&gt; Properties

        [&lt;span style="color: rgb(43,145,175)"&gt;Required&lt;/span&gt;]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; BuildDefinitionName
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_buildDefinitionName;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;            {
                m_buildDefinitionName = &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;;
            }
        }

        [&lt;span style="color: rgb(43,145,175)"&gt;Output&lt;/span&gt;]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; LastSuccessfulBuildLabel
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_lastSuccessfulBuildLabel;
            }
        }

        [&lt;span style="color: rgb(43,145,175)"&gt;Required&lt;/span&gt;]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; TeamFoundationServerUrl
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_teamFoundationServerUrl;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;            {
                m_teamFoundationServerUrl = &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;;
            }
        }

        [&lt;span style="color: rgb(43,145,175)"&gt;Required&lt;/span&gt;]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; TeamProject
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_teamProject;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;            {
                m_teamProject = &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;;
            }
        }

&lt;span style="color: rgb(0,0,255)"&gt;        #endregion

        #region&lt;/span&gt; ITask Members

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; Execute()
        {
            &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServer&lt;/span&gt; tfs = &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServerFactory&lt;/span&gt;.GetServer(TeamFoundationServerUrl);
            &lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt; buildServer = (&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;)tfs.GetService(&lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;));

            &lt;span style="color: rgb(43,145,175)"&gt;IBuildDetailSpec&lt;/span&gt; spec = buildServer.CreateBuildDetailSpec(TeamProject, BuildDefinitionName);
            spec.MaxBuildsPerDefinition = 1;
            spec.Status = &lt;span style="color: rgb(43,145,175)"&gt;BuildStatus&lt;/span&gt;.Succeeded;
            spec.QueryOrder = &lt;span style="color: rgb(43,145,175)"&gt;BuildQueryOrder&lt;/span&gt;.FinishTimeDescending;

            &lt;span style="color: rgb(43,145,175)"&gt;IBuildQueryResult&lt;/span&gt; queryResult = buildServer.QueryBuilds(spec);

            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (queryResult.Builds.Length &amp;gt; 0)
            {
                m_lastSuccessfulBuildLabel = queryResult.Builds[0].LabelName;
            }

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IBuildEngine&lt;/span&gt; BuildEngine
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_buildEngine;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;            {
                m_buildEngine = &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;;
            }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ITaskHost&lt;/span&gt; HostObject
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_taskHost;
            }
            &lt;span style="color: rgb(0,0,255)"&gt;set
&lt;/span&gt;            {
                m_taskHost = &lt;span style="color: rgb(0,0,255)"&gt;value&lt;/span&gt;;
            }
        }

&lt;span style="color: rgb(0,0,255)"&gt;        #endregion

        #region&lt;/span&gt; Private Members

        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IBuildEngine&lt;/span&gt; m_buildEngine;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ITaskHost&lt;/span&gt; m_taskHost;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; m_teamFoundationServerUrl;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; m_buildDefinitionName;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; m_teamProject;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; m_lastSuccessfulBuildLabel;

&lt;span style="color: rgb(0,0,255)"&gt;        #endregion
&lt;/span&gt;    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Note the fancy querying that is possible with an IBuildDetailSpec - pretty cool...&amp;#160; &lt;/p&gt;

&lt;p&gt;Calling the custom task should be similarly simple.&amp;#160; Something like the following should do the trick:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;BeforeGetChangesetsAndUpdateWorkItems&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;GetLastSuccessfulBuildLabel&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TeamFoundationServerUrl&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(TeamFoundationServerUrl)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                 &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TeamProject&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(TeamProject)&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; 
                                 &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;BuildDefinitionName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(BuildDefinitionName)&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Output&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TaskParameter&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;LastSuccessfulBuildLabel&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;PropertyName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;LastSuccessfulBuildLabel&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;GetLastSuccessfulBuildLabel&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;

    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;GenCheckinNotesUpdateWorkItems&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TeamFoundationServerUrl&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(TeamFoundationServerUrl)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;BuildUri&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(BuildUri)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;BuildNumber&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(BuildNumber)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;CurrentLabel&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(LabelName)@$(LabelScope)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;LastLabel&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(LastSuccessfulBuildLabel)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;UpdateWorkItems&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;$(UpdateAssociatedWorkItems)&lt;/span&gt;&amp;quot;
&lt;span style="color: rgb(0,0,255)"&gt;                                    &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;ContinueOnError&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;

  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Hope this helps!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: My original post had a typo - the property &lt;em&gt;SkipGetChangesetsAndUpdateWorkItems&lt;/em&gt; was missing its &lt;em&gt;And&lt;/em&gt;.&amp;#160; My apologies to anyone who banged their head against the wall trying to figure out why it wasn't working!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8738554" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Attaching Custom Data to a Build</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/27/attaching-custom-data-to-a-build.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/05/27/attaching-custom-data-to-a-build.aspx</id><published>2008-05-27T12:11:43Z</published><updated>2008-05-27T12:11:43Z</updated><content type="html">&lt;p&gt;In Orcas, we introduced a generic information storage for builds - internally this is used for all build steps, associated changesets/workitems, etc.&amp;#160; You can use it to attach arbitrary data to a build (and later retrieve it).&amp;#160; Here are a couple of quick code snippets to illustrate these two cases. &lt;/p&gt;  &lt;p&gt;To attach a single name/value pair to a build, you would do something like this:&lt;/p&gt;  &lt;pre class="code"&gt;        &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServer&lt;/span&gt; tfs = &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServerFactory&lt;/span&gt;.GetServer(tfsUrl);
        &lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt; buildServer = (&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;)tfs.GetService(&lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;));
        &lt;span style="color: rgb(43,145,175)"&gt;IBuildDetail&lt;/span&gt; buildDetail = buildServer.GetBuild(buildUri);

        &lt;span style="color: rgb(43,145,175)"&gt;IBuildInformationNode&lt;/span&gt; node = buildDetail.Information.CreateNode();

        node.Type = &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;MyCompany.Custom&amp;quot;&lt;/span&gt;;
        node.Fields[&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;] = &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;;

        buildDetail.Information.Save();&lt;/pre&gt;

&lt;p&gt;To retrieve the same name/value pair from the build, you would do something like this:&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServer&lt;/span&gt; tfs = &lt;span style="color: rgb(43,145,175)"&gt;TeamFoundationServerFactory&lt;/span&gt;.GetServer(tfsUrl);
        &lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt; buildServer = (&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;)tfs.GetService(&lt;span style="color: rgb(0,0,255)"&gt;typeof&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;IBuildServer&lt;/span&gt;));
        &lt;span style="color: rgb(43,145,175)"&gt;IBuildDetail&lt;/span&gt; buildDetail = buildServer.GetBuild(buildUri);

        &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;IBuildInformationNode&lt;/span&gt;&amp;gt; nodes = buildDetail.Information.GetNodesByType(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;MyCompany.Custom&amp;quot;&lt;/span&gt;);

        &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (nodes.Count &amp;gt; 0)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;IBuildInformationNode&lt;/span&gt; node &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; nodes)
            {
                &lt;span style="color: rgb(43,145,175)"&gt;String&lt;/span&gt; value = node[&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;];

                &lt;span style="color: rgb(0,128,0)"&gt;// Do something...
&lt;/span&gt;            }
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Note that the information node storage is hierarchical, so you can get a lot fancier than this if you want/need to!&amp;#160; Note that full documentation of the Orcas TFS Build Object Model can be found &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;amp;DisplayLang=en"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8554777" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Orcas RTM Object Model Documentation</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/27/orcas-rtm-object-model-documentation.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/05/27/orcas-rtm-object-model-documentation.aspx</id><published>2008-05-27T11:55:02Z</published><updated>2008-05-27T11:55:02Z</updated><content type="html">&lt;p&gt;The official Orcas RTM OM documentation was posted a while ago, and I neglected to blog about it!&amp;#160; It's available here: &lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;amp;DisplayLang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;amp;DisplayLang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;amp;DisplayLang=en&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;Make sure to follow the instructions for viewing it after downloading:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Method 1&lt;/b&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Double-click the .chm file. &lt;/li&gt;    &lt;li&gt;In the &lt;b&gt;Open File-Security Warning&lt;/b&gt; dialog box, clear the &lt;b&gt;Always ask before opening this file&lt;/b&gt; check box. &lt;/li&gt;    &lt;li&gt;Click &lt;b&gt;Open&lt;/b&gt;. &lt;/li&gt; &lt;/ol&gt; &lt;b&gt;Method 2&lt;/b&gt;  &lt;ol&gt;   &lt;li&gt;Right-click the CHM file, and then click &lt;b&gt;Properties&lt;/b&gt;. &lt;/li&gt;    &lt;li&gt;Click &lt;b&gt;Unblock&lt;/b&gt;. &lt;/li&gt;    &lt;li&gt;Double-click the .chm file to open the file. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I'm yanking the &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/14/orcas-beta-2-object-model-documentation.aspx"&gt;Beta 2 documentation&lt;/a&gt; now that this has been posted...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8554734" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Tech*Ed 2008</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/19/tech-ed-2008.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/05/19/tech-ed-2008.aspx</id><published>2008-05-19T13:37:45Z</published><updated>2008-05-19T13:37:45Z</updated><content type="html">&lt;p&gt;If you are planning on attending &lt;a href="http://www.microsoft.com/events/teched2008/developer/default.mspx"&gt;Tech*Ed Developers&lt;/a&gt; in sunny Orlando this year, I'll be manning the Visual Studio Team System 2008 Team Foundation Server (Version Control and Build) demo station (quite the name, eh?) for about 22 hours over the course of the four day event.&amp;#160; Please stop by and say hello, ask some questions, provide some feedback, etc. &lt;/p&gt;  &lt;p&gt;Other folks at the booth will include my fellow Visual Studio North Carolina folks &lt;a href="http://blogs.msdn.com/edhintz/"&gt;Ed Hintz&lt;/a&gt; (a man of many hats, including Dev Lead for the Version Control Client and Team System Web Access teams and &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=00DFCD6E-4902-4F42-8E9F-859119C60D6A&amp;amp;displaylang=en"&gt;Power Tools&lt;/a&gt; guru), and &lt;a href="http://blogs.msdn.com/crathjen/"&gt;Chris Rathjen&lt;/a&gt; (tester extraordinaire on the Admin &amp;amp; Ops team).&lt;/p&gt;  &lt;p&gt;Hope to see lots of you there!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8519046" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Orcas SP1 TFS Build Changes, Part 2</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/12/orcas-sp1-tfs-build-changes-part-2.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/05/12/orcas-sp1-tfs-build-changes-part-2.aspx</id><published>2008-05-12T13:18:15Z</published><updated>2008-05-12T13:18:15Z</updated><content type="html">&lt;p&gt;As promised, here are some more details on other SP1 changes for TFS Build.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Detect test results.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In Whidbey, a failed test would result in a failed build - builds were either Succeeded or Failed, so there wasn't really much middle ground.&amp;#160; In Orcas we added two new build status properties, CompilationStatus and TestStatus; and a new value for the overall build status - &lt;em&gt;PartiallySucceeded&lt;/em&gt;.&amp;#160; The overall status of the build would be &lt;em&gt;Succeeded&lt;/em&gt; if an only if there were no errors of any kind during the build; &lt;em&gt;PartiallySucceeded&lt;/em&gt; if no errors occurred before or during compilation; and &lt;em&gt;Failed&lt;/em&gt; otherwise.&amp;#160; If a test failed, &lt;em&gt;CompilationStatus&lt;/em&gt; would be succeeded, &lt;em&gt;TestStatus&lt;/em&gt; would be failed, and the overall &lt;em&gt;Status&lt;/em&gt; would be partially succeeded.&lt;/p&gt;  &lt;p&gt;Many users wanted a bit more control, and in particular wanted a failed test to result in a &lt;em&gt;Failed&lt;/em&gt; build.&amp;#160; I posted a workaround that allowed this &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/11/05/how-to-fail-a-build-when-tests-fail.aspx"&gt;here&lt;/a&gt;, but it was rather hacky - the idea was to set &lt;em&gt;CompilationStatus&lt;/em&gt; to failed when a test failed and then let the default logic kick in and fail the build.&amp;#160; In SP1 we introduced a new property - &lt;em&gt;TreatTestFailureAsBuildFailure&lt;/em&gt; - that will cause a test failure to fail the build without having to modify &lt;em&gt;CompilationStatus&lt;/em&gt;.&amp;#160; Just set this property to true and the new default logic will be to mark the overall status of the build as &lt;em&gt;PartiallySucceeded&lt;/em&gt; if no errors occur before or during &lt;em&gt;testing&lt;/em&gt;.&amp;#160; That is, if a test fails, &lt;em&gt;CompilationStatus&lt;/em&gt; will be succeeded, &lt;em&gt;TestStatus&lt;/em&gt; will be failed, and the overall &lt;em&gt;Status&lt;/em&gt; will be &lt;em&gt;failed&lt;/em&gt;.&amp;#160; Note that partially succeeded builds are still possible when errors occur &lt;em&gt;after&lt;/em&gt; successfully running unit tests (e.g. when copying binaries to the drop location).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. Dynamically created properties.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This one is pretty confusing, and requires an understanding of how the &lt;a href="http://msdn.microsoft.com/en-us/library/z7f65y0d.aspx"&gt;MSBuild task&lt;/a&gt; works, an understanding of the Team Build targets file, etc.&amp;#160; I'll describe the problem first, then the solution, and then for anybody who feels like sticking around just a bit about &lt;em&gt;why&lt;/em&gt; this problem exists.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The Problem&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The first time I heard about this issue, a user was dynamically generating a build number in the &lt;em&gt;BuildNumberOverrideTarget &lt;/em&gt;in the standard fashion illustrated &lt;a href="http://msdn.microsoft.com/en-us/library/aa395241.aspx"&gt;here&lt;/a&gt;, along with a corresponding version number with which to stamp assemblies.&amp;#160; He was then, however, attempting to actually &lt;em&gt;use&lt;/em&gt; that dynamically generated version number during the compilation of his individual solutions.&amp;#160; That is, he had something like:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Include&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;SomeSolution.sln&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;VersionNumber=$(VersionNumber)&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;...where $(VersionNumber) was getting generated dynamically in &lt;em&gt;BuildNumberOverrideTarget&lt;/em&gt;.&amp;#160; Unfortunately, the value getting passed into the individual solutions was the &lt;em&gt;original&lt;/em&gt; value of the property - namely, the empty string.&amp;#160; (Note that this same issue would apply if he had attempted to access the VersionNumber property in one of the &lt;em&gt;Before/AfterCompileConfiguration&lt;/em&gt; or &lt;em&gt;Before/AfterCompileSolution&lt;/em&gt; targets.)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Solution&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fix is to put all dynamically generated properties into the &lt;em&gt;CustomPropertiesForBuild&lt;/em&gt; property (or the &lt;em&gt;CustomPropertiesForClean&lt;/em&gt; property if you need to access the property in &lt;em&gt;Before/AfterCleanConfiguration&lt;/em&gt; and/or &lt;em&gt;Before/AfterCleanSolution&lt;/em&gt;).&amp;#160; For example, the user above could do something like:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Name&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;BuildNumberOverrideTarget&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;BuildNumberGenerator&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Output&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TaskParameter&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;BuildNumber&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;PropertyName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;BuildNumber&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Output&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;TaskParameter&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;VersionNumber&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;PropetyName&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt;VersionNumber&lt;/span&gt;&amp;quot;&lt;span style="color: rgb(0,0,255)"&gt; /&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;BuildNumberGenerator&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;CustomPropertiesForBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;$(CustomPropertiesForBuild);VersionNumber=$(VersionNumber)&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;CustomPropertiesForBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Target&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;em&gt;The Description&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So what the heck is going on here anyways!?&amp;#160; Well, the issue revolves around the mechanism used by Team Build to support multiproc MSBuild.&amp;#160; In particular, the unit of parallelism in MSBuild is the &lt;em&gt;project&lt;/em&gt;, meaning that to build configurations and solutions in parallel Team Build has to use the MSBuild task to call back into TfsBuild.proj for each configuration/solution combination - hence the Compile/CompileConfiguration/CompileSolution targets.&amp;#160; &lt;/p&gt;

&lt;p&gt;Furthermore, when a project is invoked with the MSBuild task, all of the environment from the caller (properties, item groups, etc.) is lost - only those properties passed in via the &lt;em&gt;Properties&lt;/em&gt; property of the MSBuild task (along with any &lt;em&gt;global&lt;/em&gt; properties - see my blog post &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/07/16/msbuild-property-evaluation.aspx"&gt;here&lt;/a&gt; for details) are available in the new context.&amp;#160; Since Team Build cannot know the full list of dynamically generated properties, none are passed into these recursive calls to TfsBuild.proj.&amp;#160; Or at least, that's how it used to work...&amp;#160; In SP1, we go ahead and pass the &lt;em&gt;CustomPropertiesForBuild&lt;/em&gt; property into the first of these recursive calls, after which any dynamically generated properties (placed into this container) become &lt;em&gt;global&lt;/em&gt; and are available for the rest of the chain.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8493997" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Orcas SP1 TFS Build Changes</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx</id><published>2008-05-05T13:16:00Z</published><updated>2008-05-05T13:16:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://blogs.msdn.com/bharry/default.aspx" mce_href="http://blogs.msdn.com/bharry/default.aspx"&gt;Brian Harry&lt;/A&gt; put up &lt;A href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx" mce_href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx"&gt;a post&lt;/A&gt; on the improvements that will be available in the upcoming Team Foundation Server 2008 SP1 release.&amp;nbsp; Here's some more in depth info on two of the TFS Build changes:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;1. Conditionalize builds on the trigger.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There are actually a few changes here...&amp;nbsp; Essentially we exposed a property on IBuildDetail called &lt;EM&gt;Reason&lt;/EM&gt; that tells you &lt;EM&gt;why&lt;/EM&gt; the build was started.&amp;nbsp; &lt;EM&gt;Reason&lt;/EM&gt; is an enum of type &lt;EM&gt;BuildReason&lt;/EM&gt;, and can have the following values:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;Manual&lt;/EM&gt;.&amp;nbsp; This indicates that the build was manually started (e.g. by a user through the Queue Build dialog).&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;IndividualCI&lt;/EM&gt;.&amp;nbsp; This indicates that the build was started due to a checkin, and that it's build definition is set up to build on each checkin.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;BatchedCI&lt;/EM&gt;.&amp;nbsp; This indicates the the build was started due to one or more checkins, and that it's build definition is set up to accumulate checkins.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Schedule&lt;/EM&gt;.&amp;nbsp; This indicates that the build was started due to the time, and that it's build definition is set up to build on a regular schedule &lt;EM&gt;if &lt;/EM&gt;changes have occurred.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;ScheduleForced&lt;/EM&gt;.&amp;nbsp; This indicates that the build was started due to the time, and that it's build definition is set up to build on a regular schedule &lt;EM&gt;whether or not&lt;/EM&gt; changes have occurred.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In addition to exposing this new property on IBuildDetail, we have also exposed it as an output property of the &lt;EM&gt;GetBuildDetails &lt;/EM&gt;task and as an MSBuild property available in your TfsBuild.proj files.&amp;nbsp; This could be useful in a couple situations:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You can use it to detect whether a build of an individual definition is running as a result of being triggered by the system &lt;EM&gt;or&lt;/EM&gt; as a result of being started manually by a user.&amp;nbsp; It may be useful to distinguish these two cases and set various properties to different default values, etc.&lt;/LI&gt;
&lt;LI&gt;When pointing more than one build definition at the &lt;EM&gt;same&lt;/EM&gt; TfsBuild.proj file (e.g. so that you can use the same script for your CI build and your Nightly build) you can use it to detect &lt;EM&gt;which&lt;/EM&gt; build definition a particular build is for.&amp;nbsp; Again, it may be useful to distinguish these two cases.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;For example, if you only wanted to generate a custom build number for your nightly build, you could do something like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;BuildNumberOverrideTarget&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Condition&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; '$(Reason)' == 'Schedule' &lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;MyBuildNumberGenerator&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;TeamFoundationServerUrl&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(TeamFoundationServerUrl)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;BuildUri&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(BuildUri)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Output&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;TaskParameter&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;BuildNumber&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;PropertyName&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;BuildNumber&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; /&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;MyBuildNumberGenerator&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;STRONG&gt;2. Reduce build log noise.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In Orcas RTM, we tried to reduce the dependency of TFS Build on the names of particular targets, tasks, events, etc. in MSBuild.&amp;nbsp; The goal was to make it more usable by people who wanted to radically customize their build process, and in general I think we did a pretty good job here.&amp;nbsp; Unfortunately, one side effect of the associated changes was the presence of lots of "noise" build steps in the Build Details dialog.&amp;nbsp; In particular, each project-to-project reference resulted in three build steps of the form:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Project 'project' is building project 'dependent project' for targets 'GetTargetPath'.&lt;/LI&gt;
&lt;LI&gt;Project 'project' is building project 'dependent project' for targets 'GetNativeManifest'.&lt;/LI&gt;
&lt;LI&gt;Project 'project' is building project 'dependent project' for targets 'GetCopyToOutputDirectoryItems'.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;These build steps should all magically disappear when Orcas SP1 is installed.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;To accomplish this, we added a property called &lt;EM&gt;TargetsNotLogged&lt;/EM&gt; to the TFS Build targets file that specifies the target names for which build steps should &lt;EM&gt;not&lt;/EM&gt; be added when our logger receives &lt;EM&gt;ProjectStarted&lt;/EM&gt; events, and made the default value of this property 'GetTargetPath;GetNativeManifest;GetCopyToOutputDirectoryItems'.&amp;nbsp; If you want these build steps back, just set the property to the empty string in your TfsBuild.proj file.&amp;nbsp; If you want to exclude other targets as well,&amp;nbsp;just set the property to your desired semicolon-delimited list of&amp;nbsp;excluded targets in your TfsBuild.proj file.&lt;/P&gt;
&lt;P&gt;(NOTE: I modified the above text on 12/30/2008 to make it more clear that the TargetsNotLogged property should be modified by overriding the default in your TfsBuild.proj file(s), &lt;EM&gt;not&lt;/EM&gt; by modifying it in place in the TFS Build targets file.)&lt;/P&gt;
&lt;P&gt;Next week I'll post on &lt;EM&gt;Detect test result&lt;/EM&gt; and/or &lt;EM&gt;Dynamically created properties&lt;/EM&gt;.&amp;nbsp; &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8460412" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Solution-Specific Output Directories in Visual Studio 2008 (Orcas)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/04/28/solution-specific-output-directories-in-visual-studio-2008-orcas.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/04/28/solution-specific-output-directories-in-visual-studio-2008-orcas.aspx</id><published>2008-04-28T12:49:00Z</published><updated>2008-04-28T12:49:00Z</updated><content type="html">&lt;P&gt;In an earlier &lt;A href="http://blogs.msdn.com/aaronhallberg/archive/2007/06/07/preserving-output-directory-structures-in-orcas-team-build.aspx" mce_href="http://blogs.msdn.com/aaronhallberg/archive/2007/06/07/preserving-output-directory-structures-in-orcas-team-build.aspx"&gt;post&lt;/A&gt; I described how one can, in Orcas, preserve the output directory structure used in a standard IDE or desktop build.&amp;nbsp; It seems that many people are looking for a simple approach, however, to augmenting the standard Team Build output directory by putting the outputs of individual solutions into individual subfolders (I get emails about this pretty regularly).&amp;nbsp; For this simple case, there is a correspondingly simple solution.&amp;nbsp; In your TfsBuild.proj file, just replace:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Include&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(BuildProjectFolderPath)/../../Directory/Solution1/Solution1.sln&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Include&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(BuildProjectFolderPath)/../../Directory/Solution2/Solution2.sln&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;...with:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Include&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(BuildProjectFolderPath)/../../Directory/Solution1/Solution1.sln&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&lt;/SPAN&gt;OutDir=$(OutDir)Solution1\&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Include&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(BuildProjectFolderPath)/../../Directory/Solution2/Solution2.sln&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&lt;/SPAN&gt;OutDir=$(OutDir)Solution2\&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;Properties&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;SolutionToBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;Note that this uses the new ability in Team Build 2008 to pass custom properties into each solution when it is built.&amp;nbsp; As shown in this earlier &lt;A href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/07/calling-custom-targets-within-team-build.aspx" mce_href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/07/calling-custom-targets-within-team-build.aspx"&gt;post&lt;/A&gt;, you can also call custom targets for each solution using the &lt;EM&gt;Targets&lt;/EM&gt; metadata also shown in this example.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8435298" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Overriding the ToolsVersion for Your Projects in Team Build</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/03/25/overriding-the-toolsversion-for-your-projects-in-team-build.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/03/25/overriding-the-toolsversion-for-your-projects-in-team-build.aspx</id><published>2008-03-25T13:48:18Z</published><updated>2008-03-25T13:48:18Z</updated><content type="html">&lt;p&gt;Recently I got a question about how to compile projects against multiple .NET Frameworks (e.g. 2.0 and 3.5) in Team Build.&amp;nbsp; MSBuild added support for this sort of thing in the 3.5 framework (they call it multi-targeting), but it is not particularly easy to take advantage of it in Team Build.&amp;nbsp; Here's the text of my response:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;MSBuild added a bunch of different mechanisms for specifying the ToolsVersion (i.e. Framework) to be used when building particular projects.&amp;nbsp; In particular:  &lt;ul&gt; &lt;li&gt;You can specify the ToolsVersion at the command-line when invoking msbuild.exe using the /tv option.  &lt;li&gt;You can specify the ToolsVersion when invoking the MSBuild task using the ToolsVersion property.  &lt;li&gt;You can specify a default ToolsVersion using the ToolsVersion attribute on the &amp;lt;Project&amp;gt; element for a particular project.  &lt;li&gt;You can specify a ToolsVersion metadata item when using the MSBuild task to build an item group containing one or more projects – see &lt;a href="http://blogs.msdn.com/msbuild/archive/2007/07/17/toolsversion-metadata-for-items-used-in-msbuild-task-s.aspx"&gt;http://blogs.msdn.com/msbuild/archive/2007/07/17/toolsversion-metadata-for-items-used-in-msbuild-task-s.aspx&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;None of these are particularly easy to use in combination with Team Build, unfortunately.&amp;nbsp; The /tv option will not work, since the Team Build traversal project (TfsBuild.proj + Microsoft.TeamFoundation.Build.targets) uses 3.5 syntax, and will not build using the 2.0 engine.&amp;nbsp; We don’t expose the ability to set ToolsVersion directly on the MSBuild task when we invoke your solution (we didn’t realize this would be useful, given the existence of the ToolsVersion attribute on the &amp;lt;Project&amp;gt; element).&amp;nbsp; And we build solutions by invoking the MSBuild task on a &lt;i&gt;property&lt;/i&gt; containing the name of your solution, so you cannot use a ToolsVersion metadata item.  &lt;p&gt;The simplest workaround here takes advantage of the properties made available by MSBuild in its generated *.sln.cache files (these are the msbuild projects created to build solutions – they used to be in-memory only, but are now typically saved to disk and reused).&amp;nbsp; In particular, something like the following should do the trick:&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Include&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;SomeSolution.sln&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;ProjectToolsVersion=3.5&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;Include&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;SomeSolution.sln&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;ProjectToolsVersion=2.0&lt;span style="color: rgb(0,0,255)"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;Properties&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;SolutionToBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;ItemGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The idea is to build the solution twice, specifying the tools version to be used each time using the &lt;i&gt;ProjectToolsVersion&lt;/i&gt; property exposed in the *.sln.cache file.&amp;nbsp; &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;There are all kinds of wacky properties exposed in the *.sln.cache files - I highly recommend taking a look at these if you're looking to do anything fancy with individual solutions in Team Build.&amp;nbsp; If you run msbuild 3.5 from the command-line on a solution, you will find a *.sln.cache file sitting alongside the *.sln file when you are done - open it up in VS (or notepad, if you're not into fancy formatting) and have a look!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8335826" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Modifying the ConfigurationFolderPath RecursionType in Team Build 2008</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/02/12/modifying-the-configurationfolderpath-recursiontype-in-team-build-2008.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/02/12/modifying-the-configurationfolderpath-recursiontype-in-team-build-2008.aspx</id><published>2008-02-12T18:20:40Z</published><updated>2008-02-12T18:20:40Z</updated><content type="html">&lt;p&gt;In TFS 2008, TfsBuild.proj files can be located anywhere in source control, not just in $/TeamProject/TeamBuildTypes, as was required in TFS 2005.&amp;nbsp; As a result, we changed the default recursion type used to download files from the configuration folder path (the location of TfsBuild.proj) to RecursionType.OneLevel, meaning that only the contents of the exact directory of TfsBuild.proj are downloaded.&amp;nbsp; The rationale here is that if you for some reason decided to put your TfsBuild.proj file at $/TeamProject, a fully recursive download would get the entire contents of the repository for that team project, which is probably not what you would want!&amp;nbsp; In some cases, however, you may wish to do a fully recursive download (if you store custom task assemblies in a subdirectory under your configuration folder path, for example), so we did provide a backdoor for changing this behavior.&amp;nbsp; In particular, you can set the &lt;em&gt;ConfigurationFolderRecursionType&lt;/em&gt; key in TfsBuildService.exe.config on your build machine to "Full" to get full recursion.&amp;nbsp; Something like:&lt;/p&gt; &lt;p&gt;&amp;lt;add key="ConfigurationFolderRecursionType" value="Full" /&amp;gt;&lt;/p&gt; &lt;p&gt;...in the &lt;em&gt;appSettings &lt;/em&gt;portion of the config file should do the trick.&amp;nbsp; Make sure to restart the service after making the change, and the next build should do a fully recursive download.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7649967" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry><entry><title>Team Build 2008 Property Reference</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/aaronhallberg/archive/2008/02/12/team-build-2008-property-reference.aspx" /><id>http://blogs.msdn.com/aaronhallberg/archive/2008/02/12/team-build-2008-property-reference.aspx</id><published>2008-02-12T15:04:00Z</published><updated>2008-02-12T15:04:00Z</updated><content type="html">&lt;p&gt;There are lots and lots of MSBuild properties available to Team Build 2008 build definitions, most of which are probably unknown to the majority of users.&amp;nbsp; As such, I've tried to compile a comprehensive list of these properties so that they can (hopefully) be more widely used.&amp;nbsp; I'll do the same thing at some point here for Team Build 2005.&amp;nbsp; If I've missed anything here or made any mistakes please let me know and I'll try and get them added/fixed.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Extensibility Properties&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;These are properties that are designed to be overridden by users, and they are already pretty well documented in MSDN &lt;a href="http://msdn2.microsoft.com/en-us/library/aa337598.aspx"&gt;here&lt;/a&gt;.&amp;nbsp; I've included the same properties here for comprehensiveness, along with some others not covered by the linked document:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;AdditionalVCOverrides&lt;/em&gt;.&amp;nbsp; These values are written to the vsprops file generated by Team Build for each C++ project compiled and passed to the &lt;em&gt;Override&lt;/em&gt; property of the &lt;em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/8xcy2245.aspx"&gt;VCBuild&lt;/a&gt;&lt;/em&gt; task.&lt;/li&gt; &lt;li&gt;&lt;em&gt;BinariesSubdirectory&lt;/em&gt;.&amp;nbsp; The subdirectory under the build agent's working directory to which binaries are redirected during compilation.&amp;nbsp; Default value is "Binaries".&lt;/li&gt; &lt;li&gt;&lt;em&gt;BuildConfigurationsInParallel&lt;/em&gt;.&amp;nbsp; Boolean property which, if true, enables building configurations (e.g. Debug|Any CPU and Release|Any CPU) in parallel, using MSBuild's multi-process capability.&amp;nbsp; Defaults to true.&amp;nbsp; Note that for this property to have an effect, the number of processes used by MSBuild, controlled by the &lt;em&gt;MaxProcesses&lt;/em&gt; key in TfsBuildService.exe.config, must be set to a number greater than one.&lt;/li&gt; &lt;li&gt;&lt;em&gt;BuildlogText&lt;/em&gt;.&amp;nbsp; The text that points to the build log in the work item created on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;BuildNumber&lt;/em&gt;.&amp;nbsp; The number of the build being built.&amp;nbsp; If you wish to override the default value, make sure to do so in the &lt;em&gt;BuildNumberOverrideTarget&lt;/em&gt; so that the standard build process logic will update the various properties that depend on the build number (the drop location, label name, etc.) properly.&lt;/li&gt; &lt;li&gt;&lt;em&gt;BuildSolutionsInParallel&lt;/em&gt;.&amp;nbsp; Boolean property which, if true, enables building solutions in parallel, using MSBuild's multi-process capability.&amp;nbsp; Defaults to true.&amp;nbsp; Note that for this property to have an effect, the number of processes used by MSBuild, controlled by the &lt;em&gt;MaxProcesses&lt;/em&gt; key in TfsBuildService.exe.config, must be set to a number greater than one.&lt;/li&gt; &lt;li&gt;&lt;em&gt;CleanCompilationOutputOnly&lt;/em&gt;.&amp;nbsp; Do not use this property directly - use &lt;em&gt;IncrementaBuild&lt;/em&gt; and/or &lt;em&gt;IncrementalGet&lt;/em&gt; instead.&lt;/li&gt; &lt;li&gt;&lt;em&gt;CreateWorkspaceTaskComment&lt;/em&gt;.&amp;nbsp; The comment used when Team Build's workspace is created.&amp;nbsp; Default value is "Workspace created by Team Build".&lt;/li&gt; &lt;li&gt;&lt;em&gt;CustomizableOutDir&lt;/em&gt;.&amp;nbsp; Set this property to true to keep Team Build from overriding the OutDir property for each solution/project in the &lt;em&gt;SolutionToBuild&lt;/em&gt; item group.&amp;nbsp; &lt;/li&gt; &lt;li&gt;&lt;em&gt;CustomizablePublishDir&lt;/em&gt;.&amp;nbsp; Set this property to true to keep Team Build from overriding the OutDir property for each solution/project in the &lt;em&gt;SolutionToPublish&lt;/em&gt; item group.&lt;/li&gt; &lt;li&gt;&lt;em&gt;CustomPropertiesForBuild&lt;/em&gt;.&amp;nbsp; Allows properties to be passed into all solutions/projects compiled during the course of the build.&lt;/li&gt; &lt;li&gt;&lt;em&gt;CustomPropertiesForClean&lt;/em&gt;.&amp;nbsp; Allows properties to be passed into all solutions/projects cleaned during the course of the build.&amp;nbsp; Note that the &lt;em&gt;Clean&lt;/em&gt; target of individual solutions/projects is only invoked if &lt;em&gt;IncrementalBuild&lt;/em&gt; is true.&lt;/li&gt; &lt;li&gt;&lt;em&gt;DescriptionText&lt;/em&gt;.&amp;nbsp; The history comment of the work item created on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;ErrorWarningLogText&lt;/em&gt;.&amp;nbsp; The text that points to the errors/warnings log file in the work item created on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;IncrementalBuild&lt;/em&gt;.&amp;nbsp; A boolean property that specifies whether the build should be full or incremental.&amp;nbsp; Defaults to false (i.e. a full build).&amp;nbsp; &lt;/li&gt; &lt;li&gt;&lt;em&gt;IncrementalGet&lt;/em&gt;.&amp;nbsp; A boolean property that specifies whether the get operation should be full or incremental.&amp;nbsp; Defaults to false (i.e. a full get).&lt;/li&gt; &lt;li&gt;&lt;em&gt;MSTestRefPath&lt;/em&gt;.&amp;nbsp; The path to the TestToolsTask (contained in Microsoft.VisualStudio.QualityTools.MSBuildTasks.dll).&amp;nbsp; Overridable so that the 8.0 version can be used for test assemblies compiled against the 8.0 unit test framework - see &lt;em&gt;V8TestToolsTask&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;&lt;em&gt;RunCodeAnalysis&lt;/em&gt;.&amp;nbsp; Property that controls whether code analysis is executed according to project settings (Default), all the time (Always), or never (Never).&lt;/li&gt; &lt;li&gt;&lt;em&gt;RunTest&lt;/em&gt;.&amp;nbsp; Boolean property that controls whether or not tests are executed.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipClean&lt;/em&gt;.&amp;nbsp; Do not use this property directly - use &lt;em&gt;IncrementalGet&lt;/em&gt; and/or &lt;em&gt;IncrementalBuild&lt;/em&gt; instead.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipDropBuild&lt;/em&gt;.&amp;nbsp; Set this property to true to skip the &lt;em&gt;CoreDropBuild&lt;/em&gt; target.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipGet&lt;/em&gt;.&amp;nbsp; Set this property to true to skip the &lt;em&gt;CoreGet&lt;/em&gt; target.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipGetChangesetsUpdateWorkItems&lt;/em&gt;.&amp;nbsp; Set this property to true to skip the association of changesets and work items for successful builds.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipInitializeWorkspace&lt;/em&gt;.&amp;nbsp; Do not use this property directly - use &lt;em&gt;IncrementalGet&lt;/em&gt; and/or &lt;em&gt;IncrementalBuild&lt;/em&gt; instead.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipInvalidConfigurations&lt;/em&gt;.&amp;nbsp; Set this property to false to generate an error rather than a warning when an invalid configuration is present in the &lt;em&gt;ConfigurationToBuild&lt;/em&gt; item group for one or more solutions/projects.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipLabel&lt;/em&gt;.&amp;nbsp; Set this property to true to skip the &lt;em&gt;CoreLabel&lt;/em&gt; target.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipPostBuild&lt;/em&gt;.&amp;nbsp; Do not use this property - use &lt;em&gt;SkipGetChangesetsUpdateWorkItems &lt;/em&gt;instead.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SkipWorkItemCreation&lt;/em&gt;.&amp;nbsp; Set this property to true to skip the &lt;em&gt;CoreCreateWorkItem&lt;/em&gt; target on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;SourcesSubdirectory&lt;/em&gt;.&amp;nbsp; The subdirectory under the build agent's working directory to which sources are retrieved from version control.&amp;nbsp; Default value is "Sources".&lt;/li&gt; &lt;li&gt;&lt;em&gt;StopOnFirstFailure&lt;/em&gt;.&amp;nbsp; Set this property to true to stop cleaning, compiling, and/or testing on the first failure encountered.&lt;/li&gt; &lt;li&gt;&lt;em&gt;TestResultsSubdirectory&lt;/em&gt;.&amp;nbsp; The subdirectory under the build agent's working directory to which test results are redirected.&amp;nbsp; Default value is "TestResults".&lt;/li&gt; &lt;li&gt;&lt;em&gt;UpdateAssociatedWorkItems&lt;/em&gt;.&amp;nbsp; A boolean value that controls whether associated work items have their "Fixed In" field updated on a successful build.&lt;/li&gt; &lt;li&gt;&lt;em&gt;UpdateAssociatedWorkItemsOnBuildBreak&lt;/em&gt;.&amp;nbsp; A boolean value that controls whether associated work items are updated for broken builds.&amp;nbsp; Default value is false.&lt;/li&gt; &lt;li&gt;&lt;em&gt;V8TestToolsTask&lt;/em&gt;.&amp;nbsp; Boolean property which, if true, causes the 8.0 TestToolsTask syntax to be used (the &lt;em&gt;TestNames &lt;/em&gt;property was not supported in the 8.0 version of the task).&lt;/li&gt; &lt;li&gt;&lt;em&gt;VCBuildAdditionaLibPaths&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;AdditionalLibPaths&lt;/em&gt; property of the &lt;em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/8xcy2245.aspx"&gt;VCBuild&lt;/a&gt;&lt;/em&gt; task for each C++ project compiled.&lt;/li&gt; &lt;li&gt;&lt;em&gt;VCBuildAdditionalOptions&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;AdditionalOptions&lt;/em&gt; property of the &lt;em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/8xcy2245.aspx"&gt;VCBuild&lt;/a&gt;&lt;/em&gt; task for each C++ project compiled.&lt;/li&gt; &lt;li&gt;&lt;em&gt;VCBuildToolPath&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;ToolPath&lt;/em&gt; property of the &lt;em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/8xcy2245.aspx"&gt;VCBuild&lt;/a&gt;&lt;/em&gt; task for each C++ project compiled.&lt;/li&gt; &lt;li&gt;&lt;em&gt;VCBuildUseEnvironment&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;UseEnvironment&lt;/em&gt; property of the &lt;em&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/8xcy2245.aspx"&gt;VCBuild&lt;/a&gt;&lt;/em&gt; task for each C++ project compiled.&lt;/li&gt; &lt;li&gt;&lt;em&gt;VCOverridesOpen&lt;/em&gt;.&amp;nbsp; The beginning of the vsprops file used to override VCBuild properties - can be overridden to use a different ProjectType version, a different Name, etc.&amp;nbsp; Default value is an escaped version of:&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt; &lt;p&gt;&amp;lt;?xml version="1.0"?&amp;gt;&lt;br&gt;&amp;lt;VisualStudioPropertySheet ProjectType="Visual C++" Version="8.00" Name="Team Build Overrides"&lt;/p&gt;&lt;/blockquote&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;VCOverridesClose&lt;/em&gt;.&amp;nbsp; The ending of the vsprops file used to override VCBuild properties.&amp;nbsp; Default value is an escaped version of:&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt; &lt;p&gt;&amp;lt;/VisualStudioPropertySheet&amp;gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;WorkItemFieldValue&lt;/em&gt;.&amp;nbsp; The fields and values of the work item created on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;WorkItemTitle&lt;/em&gt;.&amp;nbsp; The title of the work item created on a compilation failure.&lt;/li&gt; &lt;li&gt;&lt;em&gt;WorkItemType&lt;/em&gt;.&amp;nbsp; The type of work item created on a compilation failure.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Task Behavior Extensibility Properties&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;These are properties that are designed to be overridden by users to control the behavior of particular tasks (e.g. the &lt;em&gt;Get&lt;/em&gt; task).&amp;nbsp; They are organized by task.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Get (for more info, see the tf get docs &lt;a href="http://msdn2.microsoft.com/en-us/library/9ew32kd1.aspx"&gt;here&lt;/a&gt;)&lt;/li&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;ForceGet&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Force&lt;/em&gt; property of the &lt;em&gt;Get&lt;/em&gt; task.&amp;nbsp; Use of this property is discouraged - use the &lt;em&gt;IncrementalGet &lt;/em&gt;and/or &lt;em&gt;IncrementalBuild&lt;/em&gt; helper properties instead.&lt;/li&gt; &lt;li&gt;&lt;em&gt;GetOverwrite&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Overwrite&lt;/em&gt; property of the &lt;em&gt;Get&lt;/em&gt; task.&amp;nbsp; If true (the default), writable files will be overwritten automatically.&lt;/li&gt; &lt;li&gt;&lt;em&gt;RecursiveGet&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Recursive&lt;/em&gt; property of the &lt;em&gt;Get&lt;/em&gt; task.&amp;nbsp; If true (the default), the get operation will be recursive; otherwise, the get operation will only get top-level files and directories.&lt;/li&gt; &lt;li&gt;&lt;em&gt;GetVersion&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Version&lt;/em&gt; property of the &lt;em&gt;Get &lt;/em&gt;task.&amp;nbsp; Defaults to &lt;em&gt;SourceGetVersion&lt;/em&gt; (see below), but can be overridden to retrieve a particular version from source control.&lt;/li&gt; &lt;li&gt;&lt;em&gt;GetFileSpec&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Filespec&lt;/em&gt; property of the &lt;em&gt;Get&lt;/em&gt; task.&amp;nbsp; Defaults to empty, signifying that the entire contents of the workspace should be retrieved.&lt;/li&gt; &lt;li&gt;&lt;em&gt;GetPopulateOutput&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;PopulateOutput&lt;/em&gt; property of the &lt;em&gt;Get&lt;/em&gt; task - controls whether the &lt;em&gt;Gets&lt;/em&gt;, &lt;em&gt;Replaces&lt;/em&gt;, and &lt;em&gt;Deletes&lt;/em&gt; properties of the &lt;em&gt;Get&lt;/em&gt; task are populated (these provide access to the new files retrieved from version control, the files modified during the get, and the files deleted during the get).&amp;nbsp; Default value is false.&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Label (for more info, see the tf label docs &lt;a href="http://msdn2.microsoft.com/en-us/library/9ew32kd1.aspx"&gt;here&lt;/a&gt;)&lt;/li&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;LabelRecursive&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Recursive&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task.&amp;nbsp; If true (the default), the label operation will be recursive; otherwise, the label operation will only label top-level files and directories.&lt;/li&gt; &lt;li&gt;&lt;em&gt;LabelChild&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Child&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task.&amp;nbsp; Valid values are &lt;em&gt;Merge &lt;/em&gt;or &lt;em&gt;Replace&lt;/em&gt;, with the default being &lt;em&gt;Replace&lt;/em&gt;.&amp;nbsp; &lt;/li&gt; &lt;li&gt;&lt;em&gt;LabelComment&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Comment&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task, this property controls the comment text used by the label operation.&amp;nbsp; Default value is "Label created by Team Build".&lt;/li&gt; &lt;li&gt;&lt;em&gt;LabelName&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Name&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task, this property controls the name of the label generated by the label operation.&amp;nbsp; Default value is the build number.&lt;/li&gt; &lt;li&gt;&lt;em&gt;LabelFiles&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Files&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task, this property controls the files labeled by the label operation.&amp;nbsp; Default value is "$/", or every file mapped in the workspace.&lt;/li&gt; &lt;li&gt;&lt;em&gt;LabelScope&lt;/em&gt;.&amp;nbsp; Passed to the &lt;em&gt;Scope&lt;/em&gt; property of the &lt;em&gt;Label&lt;/em&gt; task, this property controls the scope of the label generated by the label operation.&amp;nbsp; Default value is "$/$(TeamProject)".&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Other Useful Properties&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;These are properties that are used by the build process and should not be modified.&amp;nbsp; They can, however, be used to execute logic conditionally, to parameterize custom logic in the build process, etc.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;em&gt;BinariesRoot&lt;/em&gt;.&amp;nbsp; The root directory for binaries - typically the working directory for the build agent + the &lt;em&gt;BinariesSubdirectory&lt;/em&gt; property (see above). &lt;li&gt;&lt;em&gt;BuildAgentName&lt;/em&gt;.&amp;nbsp; The name of the build agent running the build. &lt;li&gt;&lt;em&gt;BuildAgentUri&lt;/em&gt;.&amp;nbsp; The URI of the build agent running the build. &lt;li&gt;&lt;em&gt;BuildBreak&lt;/em&gt;.&amp;nbsp; Set to true when a compilation error occurs, otherwise false.&amp;nbsp; Can be used in build break targets to determine whether they are executing after a compilation error or executing normally. &lt;li&gt;&lt;em&gt;BuildDefinition&lt;/em&gt;.&amp;nbsp; This property provides the name of the definition being built.  &lt;li&gt;&lt;em&gt;BuildDefinitionId&lt;/em&gt;.&amp;nbsp; This property provides the integer ID of the definition being built.  &lt;li&gt;&lt;em&gt;BuildDefinitionName&lt;/em&gt;.&amp;nbsp; See &lt;em&gt;BuildDefinition&lt;/em&gt;.  &lt;li&gt;&lt;em&gt;BuildDefinitionUri&lt;/em&gt;.&amp;nbsp; The URI of the build definition being built. &lt;li&gt;&lt;em&gt;BuildDirectory&lt;/em&gt;.&amp;nbsp; The local directory being used for the build, corresponding to the expanded working directory of the build agent being used.  &lt;li&gt;&lt;em&gt;BuildProjectFolderPath&lt;/em&gt;.&amp;nbsp; This property provides the version control path to the TfsBuild.proj file being run, and corresponds to the ConfigurationFolderPath property of the build definition.  &lt;li&gt;&lt;em&gt;BuildUri&lt;/em&gt;.&amp;nbsp; The URI of the executing build.  &lt;li&gt;&lt;em&gt;ConfigurationFolderUri&lt;/em&gt;.&amp;nbsp; The version control URI of the directory that contains the TfsBuild.proj file being run. &lt;li&gt;&lt;em&gt;DropLocation&lt;/em&gt;.&amp;nbsp; This property provides the "root" drop location for the build - either the DefaultDropLocation of the build definition or the overridden drop location provided when the build was queued.  &lt;li&gt;&lt;em&gt;IsDesktopBuild&lt;/em&gt;.&amp;nbsp; True for desktop builds, false for "standard" build machine builds.  &lt;li&gt;&lt;em&gt;LastBuildNumber&lt;/em&gt;.&amp;nbsp; The number of the last build, regardless of its status.  &lt;li&gt;&lt;em&gt;LastGoodBuildLabel&lt;/em&gt;.&amp;nbsp; The label created by the last "good" build.&amp;nbsp; This is the label that will be used to associate changesets and work items with the current build.  &lt;li&gt;&lt;em&gt;LastGoodBuildNumber&lt;/em&gt;.&amp;nbsp; The number of the last good build.  &lt;li&gt;&lt;em&gt;MachineName&lt;/em&gt;.&amp;nbsp; The machine name of the build agent running the build. &lt;li&gt;&lt;em&gt;MaxProcesses&lt;/em&gt;.&amp;nbsp; The maximum number of processes being used by MSBuild. &lt;li&gt;&lt;em&gt;Port&lt;/em&gt;.&amp;nbsp; The port being used by the build agent running the build. &lt;li&gt;&lt;em&gt;NoCICheckinComment&lt;/em&gt;.&amp;nbsp; The comment which must be included in a checkin to prevent continuous integration from triggering a build.&amp;nbsp; This is critical for CI builds that need to check files in to avoid triggering an infinite loop of builds.  &lt;li&gt;&lt;em&gt;Reason&lt;/em&gt;.&amp;nbsp; (SP1 and later only)&amp;nbsp; The reason the build was started - &lt;em&gt;None&lt;/em&gt; indicates the build was manually queued, &lt;em&gt;Individual&lt;/em&gt; indicates that a "build every checkin" trigger caused the build, &lt;em&gt;Batch&lt;/em&gt; indicates that a "rolling build" trigger caused the build, &lt;em&gt;Schedule&lt;/em&gt; indicates that a scheduled trigger caused the build, and &lt;em&gt;ScheduleForced&lt;/em&gt; indicates that a scheduled trigger that builds whether or not changes have occurred since the last build caused the build. &lt;li&gt;&lt;em&gt;RequestedBy&lt;/em&gt;.&amp;nbsp; The user that requested the build - for triggered builds, this will typically be a service account. &lt;li&gt;&lt;em&gt;RequestedFor&lt;/em&gt;.&amp;nbsp; The user for whom the build was requested - for CI builds, this will be the user whose checkin triggered the build. &lt;li&gt;&lt;em&gt;SolutionRoot&lt;/em&gt;.&amp;nbsp; The root directory for source files retrieved from version control - typically the working directory for the build agent + the &lt;em&gt;SourcesSubdirectory&lt;/em&gt; property (see above). &lt;li&gt;&lt;em&gt;SourceGetVersion&lt;/em&gt;.&amp;nbsp; The version spec that will be used to retrieve sources for the build, unless the &lt;em&gt;GetVersion&lt;/em&gt; property is overridden.  &lt;li&gt;&lt;em&gt;StartTime&lt;/em&gt;.&amp;nbsp; The time at which the build started. &lt;li&gt;&lt;em&gt;TeamBuildConstants&lt;/em&gt;.&amp;nbsp; Allows projects being compiled to determine whether Team Build is compiling them.&amp;nbsp; Default value is "_TEAM_BUILD_". &lt;li&gt;&lt;em&gt;TeamBuildOutDir&lt;/em&gt;.&amp;nbsp; The directory Team Build would have set &lt;em&gt;OutDir&lt;/em&gt; true if &lt;em&gt;CustomizableOutDir&lt;/em&gt; and/or &lt;em&gt;CustomizablePublishDir&lt;/em&gt; (see above) were false.&amp;nbsp; If both are true, this value is equivalent to &lt;em&gt;OutDir&lt;/em&gt;.&amp;nbsp; &lt;li&gt;&lt;em&gt;TeamBuildRefPath&lt;/em&gt;.&amp;nbsp; Provides the path to Team Build binaries (the logger, tasks, etc.).&amp;nbsp; Typically %ProgramFiles%\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies.  &lt;li&gt;&lt;em&gt;TeamBuildVersion&lt;/em&gt;.&amp;nbsp; This property is set to 2.0 in Team Build 2008 and will be incremented in subsequent versions.  &lt;li&gt;&lt;em&gt;TeamFoundationServerUrl&lt;/em&gt;.&amp;nbsp; The URL of the team foundation server that owns the executing build.  &lt;li&gt;&lt;em&gt;TeamProject&lt;/em&gt;.&amp;nbsp; The team project of the build definition being built. &lt;li&gt;&lt;em&gt;TestResultsRoot&lt;/em&gt;.&amp;nbsp; The root directory for test results - typically the working directory for the build agent + the &lt;em&gt;TestResultsSubdirectory&lt;/em&gt; property (see above). &lt;li&gt;&lt;em&gt;WorkspaceName&lt;/em&gt;.&amp;nbsp; The name of the workspace used to retrieve sources from version control.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Target Dependency Properties&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;These are the properties used to set up the target dependency hierarchy in Team Build.&amp;nbsp; The can be modified to insert custom targets into the build process as an alternative to overriding the provided extensibility targets, but this should be done with care.&amp;nbsp; The standard pattern for overriding a dependency property is something like the following:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;DesktopBuildDependsOn&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;      PreDesktopBuildTarget;
      $(DesktopBuildDependsOn);
      PostDesktopBuildTarget;
&lt;span style="color: rgb(0,0,255)"&gt;    &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;DesktopBuildDependsOn&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;    
  &amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163,21,21)"&gt;PropertyGroup&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Note that the initial value of the property is preserved and new values are simply inserted before and after the existing ones, making sure to include semi-colons in all the appropriate spots.&amp;nbsp; For more information on these properties, you'll need to comb through the targets file - a full explanation of their functionality is beyond the scope of this blog post!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;CleanDependsOn.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CleanAllDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CleanCompilationOutputDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CleanConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CleanSolutionDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CompileDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CompileConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CompileSolutionDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;ComputeSolutionListDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCompileDependsOn&lt;/em&gt;.&amp;nbsp; (This one is for backwards compatibility with TFS 2005 target overrides)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;_CoreCompileDependsOn&lt;/em&gt;.&amp;nbsp; (This one is the new &lt;em&gt;CoreCompileDependsOn &lt;/em&gt;for TFS 2008)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCompileConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCleanDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCleanAllDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCleanCompilationOutputDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCleanConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreCreateWorkItemDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreDropBuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreGetChangesetsAndUpdateWorkItemsDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreGetChangesetsOnBuildBreakDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreGetDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreInitializeWorkspaceDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreLabelDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreOnBuildBreakDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreTestDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CoreTestConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;CreateWorkItemDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;DesktopBuildDependsOn&lt;/em&gt;.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&lt;em&gt;DesktopRebuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;DropBuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;EndToEndIterationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;GetChangesetsAndUpdateWorkItemsDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;GetChangesetsOnBuildBreakDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;GetDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;InitializeWorkspaceDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;LabelDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;OnBuildBreakDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;PostBuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;PreBuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;RunTestDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;TeamBuildDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;TestConfigurationDependsOn&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;TestDependsOn&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7644736" width="1" height="1"&gt;</content><author><name>aaronhallberg</name><uri>http://blogs.msdn.com/members/aaronhallberg.aspx</uri></author></entry></feed>