<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Aaron Hallberg</title><link>http://blogs.msdn.com/b/aaronhallberg/</link><description>Team Build (Build Automation) - Visual Studio North Carolina</description><dc:language>en</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Lots of Good Blog Content</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2009/12/22/lots-of-good-blog-content.aspx</link><pubDate>Tue, 22 Dec 2009 21:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9940246</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=9940246</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2009/12/22/lots-of-good-blog-content.aspx#comments</comments><description>&lt;P&gt;I've been neglecting my blogging duties for the past many months while we finish off the bulk of Dev 10 - sorry about that.&amp;nbsp; In the meantime, lots of other folks have posted lots of good TFS Build 2010 content, including:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jimlamb"&gt;&lt;FONT color=#0000cc&gt;Jim Lamb&lt;/FONT&gt;&lt;/A&gt;'s post on &lt;A href="http://blogs.msdn.com/jimlamb/archive/2009/11/18/how-to-create-a-custom-workflow-activity-for-tfs-build-2010.aspx"&gt;&lt;FONT color=#0000cc&gt;creating a custom workflow activity for TFS Build 2010&lt;/FONT&gt;&lt;/A&gt;.&amp;nbsp; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/patcarna/"&gt;&lt;FONT color=#0000cc&gt;Patrick Carnahan&lt;/FONT&gt;&lt;/A&gt;'s posts on customizing build information (&lt;A href="http://blogs.msdn.com/patcarna/archive/2009/11/17/tfs-2010-customizing-build-information.aspx"&gt;&lt;FONT color=#0000cc&gt;part 1&lt;/FONT&gt;&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/patcarna/archive/2009/11/19/tfs-2010-customizing-build-information-part-2.aspx"&gt;&lt;FONT color=#0000cc&gt;part 2&lt;/FONT&gt;&lt;/A&gt;), and an &lt;A href="http://blogs.msdn.com/patcarna/archive/2009/12/04/introduction-to-windows-workflow-4-0.aspx"&gt;&lt;FONT color=#0000cc&gt;Introduction to Windows Workflow 4.0&lt;/FONT&gt;&lt;/A&gt;. 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/adamroot/"&gt;&lt;FONT color=#0000cc&gt;Adam Root&lt;/FONT&gt;&lt;/A&gt;'s workaround for a &lt;A href="http://blogs.msdn.com/adamroot/archive/2009/12/10/building-vs-2008-unit-test-projects-in-msbuild-4-0-beta-2.aspx"&gt;&lt;FONT color=#0000cc&gt;Beta 2 bug&lt;/FONT&gt;&lt;/A&gt; where 9.0 test projects end up with a bogus reference to the 4.0 framework and fail with a BadImageFormatException. 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jpricket"&gt;&lt;FONT color=#0000cc&gt;Jason Prickett&lt;/FONT&gt;&lt;/A&gt;'s posts on new &lt;A href="http://blogs.msdn.com/jpricket/archive/2009/12/09/tfs-2010-how-about-those-build-delete-options.aspx"&gt;&lt;FONT color=#0000cc&gt;build deletion options&lt;/FONT&gt;&lt;/A&gt;, &lt;A href="http://blogs.msdn.com/jpricket/archive/2009/12/21/tfs-2010-displaying-custom-build-information-in-visual-studio.aspx"&gt;&lt;FONT color=#0000cc&gt;displaying custom build information&lt;/FONT&gt;&lt;/A&gt; in Visual Studio, and &lt;A href="http://blogs.msdn.com/jpricket/archive/2009/12/22/tfs2010-changing-the-way-build-information-is-displayed.aspx"&gt;&lt;FONT color=#0000cc&gt;modifying the default display of build information&lt;/FONT&gt;&lt;/A&gt; in Visual Studio. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There should be lots more good stuff coming on all these blogs, and on my own, over the next weeks and months.&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9940246" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/aaronhallberg/archive/tags/TFS+Build+2010/">TFS Build 2010</category></item><item><title>Writing Custom Activities for TFS Build 2010 (Beta 1)</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2009/06/01/writing-custom-activities-for-tfs-build-2010-beta-1.aspx</link><pubDate>Mon, 01 Jun 2009 17:49:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9678214</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=9678214</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2009/06/01/writing-custom-activities-for-tfs-build-2010-beta-1.aspx#comments</comments><description>&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;</description><category domain="http://blogs.msdn.com/b/aaronhallberg/archive/tags/VSTS2010/">VSTS2010</category></item><item><title>TargetsNotLogged Hotfix Available</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2009/01/30/targetsnotlogged-hotfix-available.aspx</link><pubDate>Fri, 30 Jan 2009 19:14:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9384921</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=9384921</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2009/01/30/targetsnotlogged-hotfix-available.aspx#comments</comments><description>&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;</description></item><item><title>Calling Custom Targets in Team Build, Part 3</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/12/30/calling-custom-targets-in-team-build-part-3.aspx</link><pubDate>Wed, 31 Dec 2008 00:13:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9257620</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=9257620</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/12/30/calling-custom-targets-in-team-build-part-3.aspx#comments</comments><description>&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;</description></item><item><title>The CompilationOutputs Item Group</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/08/08/the-compilationoutputs-item-group.aspx</link><pubDate>Fri, 08 Aug 2008 20:49:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8843914</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8843914</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/08/08/the-compilationoutputs-item-group.aspx#comments</comments><description>&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;</description></item><item><title>A Minimal TFSBuild.Proj File</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/07/28/a-minimal-tfsbuild-proj-file.aspx</link><pubDate>Mon, 28 Jul 2008 17:31:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8784395</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8784395</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/07/28/a-minimal-tfsbuild-proj-file.aspx#comments</comments><description>&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;</description></item><item><title>Associating changesets and Work Items Since the Last Successful Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/07/16/associating-changesets-and-work-items-since-the-last-successful-build.aspx</link><pubDate>Wed, 16 Jul 2008 16:40:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8738554</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8738554</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/07/16/associating-changesets-and-work-items-since-the-last-successful-build.aspx#comments</comments><description>&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;</description></item><item><title>Attaching Custom Data to a Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/27/attaching-custom-data-to-a-build.aspx</link><pubDate>Tue, 27 May 2008 15:11:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8554777</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8554777</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/27/attaching-custom-data-to-a-build.aspx#comments</comments><description>&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;</description></item><item><title>Orcas RTM Object Model Documentation</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/27/orcas-rtm-object-model-documentation.aspx</link><pubDate>Tue, 27 May 2008 14:55:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8554734</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8554734</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/27/orcas-rtm-object-model-documentation.aspx#comments</comments><description>&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;</description></item><item><title>Tech*Ed 2008</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/19/tech-ed-2008.aspx</link><pubDate>Mon, 19 May 2008 16:37:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8519046</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8519046</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/19/tech-ed-2008.aspx#comments</comments><description>&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;</description></item><item><title>Orcas SP1 TFS Build Changes, Part 2</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/12/orcas-sp1-tfs-build-changes-part-2.aspx</link><pubDate>Mon, 12 May 2008 16:18:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8493997</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8493997</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/12/orcas-sp1-tfs-build-changes-part-2.aspx#comments</comments><description>&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;</description></item><item><title>Orcas SP1 TFS Build Changes</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx</link><pubDate>Mon, 05 May 2008 16:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8460412</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8460412</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx#comments</comments><description>&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;</description></item><item><title>Solution-Specific Output Directories in Visual Studio 2008 (Orcas)</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/04/28/solution-specific-output-directories-in-visual-studio-2008-orcas.aspx</link><pubDate>Mon, 28 Apr 2008 15:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8435298</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8435298</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/04/28/solution-specific-output-directories-in-visual-studio-2008-orcas.aspx#comments</comments><description>&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;</description></item><item><title>Overriding the ToolsVersion for Your Projects in Team Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/03/25/overriding-the-toolsversion-for-your-projects-in-team-build.aspx</link><pubDate>Tue, 25 Mar 2008 16:48:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8335826</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=8335826</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/03/25/overriding-the-toolsversion-for-your-projects-in-team-build.aspx#comments</comments><description>&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;</description></item><item><title>Modifying the ConfigurationFolderPath RecursionType in Team Build 2008</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/12/modifying-the-configurationfolderpath-recursiontype-in-team-build-2008.aspx</link><pubDate>Tue, 12 Feb 2008 21:20:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7649967</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=7649967</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/12/modifying-the-configurationfolderpath-recursiontype-in-team-build-2008.aspx#comments</comments><description>&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;</description></item><item><title>Team Build 2008 Property Reference</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/12/team-build-2008-property-reference.aspx</link><pubDate>Tue, 12 Feb 2008 18:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7644736</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>17</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=7644736</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/12/team-build-2008-property-reference.aspx#comments</comments><description>&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;</description></item><item><title>Calling Custom Targets Within Team Build, Part 2</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/08/calling-custom-targets-within-team-build-part-2.aspx</link><pubDate>Fri, 08 Feb 2008 17:02:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7541022</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=7541022</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2008/02/08/calling-custom-targets-within-team-build-part-2.aspx#comments</comments><description>&lt;p&gt;First of all, sorry for the long delay between posts...&amp;nbsp; Things have been a bit crazy around here trying to meet various deadlines lately, and blogging fell right off my radar for a while.&amp;nbsp; Having said that, I've got a pretty big backlog of posts to get done, so hopefully I'll get a bunch posted here in the near future.&lt;/p&gt; &lt;p&gt;I've gotten several questions over the past month or so on calling custom targets defined in TfsBuild.proj for each solution/project built and/or for each configuration (e.g. Debug / Any CPU) built.&amp;nbsp; I did a &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/07/calling-custom-targets-within-team-build.aspx"&gt;post&lt;/a&gt; a while back on calling custom targets, but it was mostly focused on calling targets other than the default (typically "Build") in the solutions/projects included in the SolutionToBuild item group within TfsBuild.proj.&amp;nbsp; That is, these custom targets would be &lt;em&gt;in the solution / project itself&lt;/em&gt;, not in TfsBuild.proj.&lt;/p&gt; &lt;p&gt;In Team Build 2008, we added several new extension points that allow you to execute custom targets within TfsBuild.proj before / after the compilation of individual solution and/or configurations.&amp;nbsp; In particular, in Team Build 2005 the compilation portion of the build process included just the following targets (with targets designed to be overridden given in &lt;strong&gt;bold&lt;/strong&gt;):&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;BeforeCompile&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;CoreCompile&lt;/p&gt; &lt;p&gt;&lt;strong&gt;AfterCompile&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;And that was it...&amp;nbsp; CoreCompile built every solution for every configuration.&amp;nbsp; If you wanted to inject some custom logic anywhere other than before this entire process or after this entire process, you were basically out of luck.&amp;nbsp; In Team Build 2008, the compilation portion of the build process includes the following targets:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;BeforeCompile&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;CoreCompile&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (for each configuration)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;BeforeCompileConfiguration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;CoreCompileConfiguration&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (for each solution)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;BeforeCompileSolution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;CoreCompileSolution&lt;/p&gt; &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;AfterCompileSolution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AfterCompileConfiguration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;AfterCompile&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Additionally, several properties are available in the relevant spots in this process to help you execute logic conditionally.&amp;nbsp; In particular, within each iteration of the *CompileConfiguration targets, the properties $(Platform) and $(Configuration) will provide the currently compiling platform and configuration; and within each iteration of the *CompileSolution targets, the property $(Solution) will provide the currently compiling solution.&amp;nbsp; &lt;/p&gt; &lt;p&gt;So - to execute custom logic for each solution, you can either insert that logic directly into the Before/AfterCompileSolution target, use the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms229474.aspx"&gt;CallTarget&lt;/a&gt; task to explicitly call your target, etc.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7541022" width="1" height="1"&gt;</description></item><item><title>How Would You Spend $100 On MSBuild?</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/11/19/how-would-you-spend-100-on-msbuild.aspx</link><pubDate>Mon, 19 Nov 2007 16:54:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6400859</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=6400859</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/11/19/how-would-you-spend-100-on-msbuild.aspx#comments</comments><description>&lt;p&gt;The MSBuild team is looking for some feedback from the community to keep their "vision" for the next version of MSBuld aligned with their customers wants and needs.&amp;nbsp; They've got a blog post up &lt;a href="http://blogs.msdn.com/msbuild/archive/2007/11/17/how-would-you-spend-100-on-msbuild.aspx"&gt;here&lt;/a&gt; that asks for you, the MSBuild experts out there, to rank various potential new features they could work on.&amp;nbsp; Here are the various options (with fuller descriptions elided):&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Higher performance multiprocessor support...&lt;/li&gt; &lt;li&gt;VC support...&lt;/li&gt; &lt;li&gt;Support for other Microsoft project types that aren't yet in MSBuild format: Deployment/MSI (*.vdproj), SQL Reporting (*.rptproj), Biztalk (*.btproj), Prompt (*.prproj), etc...&lt;/li&gt; &lt;li&gt;Conversion of Visual Studio solution files (*.sln)...&lt;/li&gt; &lt;li&gt;Extensible up-to-date checking...&lt;/li&gt; &lt;li&gt;Distributed build...&lt;/li&gt; &lt;li&gt;Extensible re-usable inline tasks...&lt;/li&gt; &lt;li&gt;Typing and scoping for items and properties.&lt;/li&gt; &lt;li&gt;Extensible functions...&lt;/li&gt; &lt;li&gt;An MSBuild debugger...&lt;/li&gt; &lt;li&gt;Visualization for project and target dependencies...&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Personally, my vote would be to spend $50 on getting the full solution/project system MSBuild compliant (#'s 2, 3, and 4), $40 on the debugger (#10), and $10 on the miscellaneous syntax improvements (#'s 8, 7, and 9 - in that order).&amp;nbsp; The rest of the features (improved multiprocessor support, distributed build, project/target dependency visualization) target what I would think would be a&amp;nbsp;pretty small segment of the market, especially given the current lack of real VC support.&amp;nbsp; &lt;/p&gt; &lt;p&gt;But hey, what do I know!?&amp;nbsp; Go to the &lt;a href="http://blogs.msdn.com/msbuild/archive/2007/11/17/how-would-you-spend-100-on-msbuild.aspx"&gt;original post&lt;/a&gt; and share your priorities with the MSBuild team.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6400859" width="1" height="1"&gt;</description></item><item><title>How to: Fail a Build When Tests Fail</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/11/05/how-to-fail-a-build-when-tests-fail.aspx</link><pubDate>Mon, 05 Nov 2007 17:36:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5910722</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5910722</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/11/05/how-to-fail-a-build-when-tests-fail.aspx#comments</comments><description>&lt;p&gt;Got an email from &lt;a href="http://www.woodwardweb.com/"&gt;Martin Woodward&lt;/a&gt; this morning asking:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;What would be your preferred way to fully fail the build on test failure rather than partially succeed the build?&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;A bit of background - Team Build 2008 marks builds as &lt;em&gt;Succeeded&lt;/em&gt; if no errors are encountered during the build process, &lt;em&gt;Partially Succeeded&lt;/em&gt; if compilation succeeds but an error is encountered at some other stage of the build process (e.g. a unit test fails), and &lt;em&gt;Failed&lt;/em&gt; otherwise.&amp;nbsp; Depending on where you are in your development process, this logic may or may not make sense to you.&amp;nbsp; For example, if you are two weeks away from shipping your product, a unit test failure might be just as important to you as a compilation failure.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The design of Team Build 2008 doesn't really allow for setting the overall status of the build directly - the setting of the build status is what indicates to TFS that the build is "complete", which triggers the build queue logic to start up the next build, etc.&amp;nbsp; As such, you really shouldn't ever set this property of the build yourself!&lt;/p&gt; &lt;p&gt;You can get around this by setting the properties Team Build uses to determine the overall status of the build, however - CompilationStatus, TestStatus, and an internal logger property that keeps track of whether &lt;em&gt;any&lt;/em&gt; errors have occurred.&amp;nbsp; Note the above algorithm for determining status one more time - &lt;em&gt;Succeeded&lt;/em&gt; if no errors are encountered, &lt;em&gt;Partially Succeeded&lt;/em&gt; if &lt;em&gt;CompilationStatus&lt;/em&gt; is &lt;em&gt;Succeeded&lt;/em&gt; but an error occurs at some other stage, and &lt;em&gt;Failed &lt;/em&gt;otherwise.&amp;nbsp; So - if you want the overall status of the build to be &lt;em&gt;Failed&lt;/em&gt;, you'll need to set &lt;em&gt;CompilationStatus&lt;/em&gt; to &lt;em&gt;Failed&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;So -&amp;nbsp;here is my recommended approach:&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;AfterTest&lt;/span&gt;"&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; Refresh the build 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;GetBuildProperties&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;                        &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; '$(IsDesktopBuild)' != 'true' &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;TestSuccess&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;TestSuccess&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;GetBuildProperties&lt;/span&gt;&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; Set CompilationStatus to Failed if TestSuccess is false. &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;SetBuildProperties&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;                        &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;CompilationStatus&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;Failed&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; '$(IsDesktopBuild)' != 'true' and '$(TestSuccess)' != 'true' &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;The idea here is to check whether or not tests have succeeded (see my previous post &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/07/13/determining-whether-tests-passed-in-team-build-orcas.aspx"&gt;here&lt;/a&gt; on this topic) and then update the CompilationStatus (and thus the overall Status) of the build accordingly.&amp;nbsp; If you want the build to halt immediately in addition to marking the status as Failed, you can use an &lt;a href="http://msdn2.microsoft.com/en-us/library/8b08t3s4.aspx"&gt;Error&lt;/a&gt; task, and you'll probably also want to move the logic to the &lt;em&gt;AfterTestConfiguration&lt;/em&gt; target (to avoid running tests for each configuration before halting the build).&amp;nbsp; 
&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5910722" width="1" height="1"&gt;</description></item><item><title>Building VC++ 2005 Projects With Team Build 2008</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/30/building-vc-2005-projects-with-team-build-2008.aspx</link><pubDate>Tue, 30 Oct 2007 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5781592</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5781592</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/30/building-vc-2005-projects-with-team-build-2008.aspx#comments</comments><description>&lt;P&gt;MSBuild introduced a &lt;A href="http://blogs.msdn.com/msbuild/archive/2006/11/03/msbuild-orcas-and-multi-targeting.aspx" mce_href="http://blogs.msdn.com/msbuild/archive/2006/11/03/msbuild-orcas-and-multi-targeting.aspx"&gt;multi-targeting&lt;/A&gt; feature in VS 2008 that allows it to build managed code projects that target previous versions of the .NET Framework (and all associated tools - the Microsoft.Common.targets file, the MSBuild engine itself, etc.).&amp;nbsp; Unfortunately, there is no corresponding functionality for VC++ projects, since these are &lt;EM&gt;still&lt;/EM&gt; not MSBuild compatible project files.&amp;nbsp; MSBuild can build &lt;EM&gt;solutions&lt;/EM&gt; containing VC++ projects, but there will be issues when building solutions containing VC++ 2005 (version 8) projects with the VS 2008 MSBuild engine (.NET Framework version 3.5) and thus with Team Build 2008.&lt;/P&gt;
&lt;P&gt;In particular, you will notice messages similar to the following in your build log:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;vcbuild.exe : error VCBLD0010: Project '&amp;lt;project name&amp;gt;' requires upgrade. Use 'vcbuild /upgrade' or 'devenv /upgrade' to upgrade the project.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The project file that MSBuild generates to build solutions uses something like the following VCBuild task invocation to build VC++ projects:&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;VCBuild&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Projects&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;foo.vcproj&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;ToolPath&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(VCBuildToolPath)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Configuration|Platform&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;SolutionFile&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;foo.sln&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;Override&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(VCBuildOverride)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;AdditionalLibPaths&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(VCBuildAdditionalLibPaths)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;UserEnvironment&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(VCBuildUserEnvironment)&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; 
         &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(255,0,0)"&gt;AdditionalOptions&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;$(VCBuildAdditionalOptions)&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; ('$(Configuration)' == 'Configuration') and ('$(Platform)' == 'Platform') &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;The trick is that this will always use the VCBuild task from the 3.5 .NET Framework directory, and this task will always invoke VCBuild 2008.&amp;nbsp; Note, however, the &lt;EM&gt;VCBuildToolPath&lt;/EM&gt; property - this allows you to override the path to vcbuild.exe used by the task, and provides the workaround that allows building VC++ 2005 projects without upgrading them.&lt;/P&gt;
&lt;P&gt;In particular, you can add something like the following text to your TfsBuild.rsp file if &lt;EM&gt;all&lt;/EM&gt; the solutions in your Team Build build contain VC++ 2005 projects:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;/p:vcbuildtoolpath="$(ProgramFiles)\Microsoft Visual Studio 8\vc\vcpackages"&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If some of your solutions contain VC++ 2005 projects and some contain VC++ 2008 projects, you can specify the property on a solution-specific basis using the &lt;EM&gt;Properties&lt;/EM&gt; metadata of the &lt;EM&gt;SolutionToBuild&lt;/EM&gt; item group as follows:&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;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;VCBuild_2005.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;vcbuildtoolpath=$(ProgramFiles)\Microsoft Visual Studio 8\vc\vcpackages&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;VCBuild_2008.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;&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;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5781592" width="1" height="1"&gt;</description></item><item><title>Error MSB3021 and Team Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/22/error-msb3021-and-team-build.aspx</link><pubDate>Mon, 22 Oct 2007 20:37:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5605289</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5605289</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/22/error-msb3021-and-team-build.aspx#comments</comments><description>&lt;p&gt;The error message "&lt;font face="Arial"&gt;error MSB3021: Unable to copy file "&amp;lt;filename&amp;gt;" to "&amp;lt;output location&amp;gt;". Access to the path '&amp;lt;output location&amp;gt;' is denied&lt;/font&gt;" occurs when the MSBuild Copy task cannot overwrite an existing read-only file.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Typically in Team Build this error will occur because (a) there seems to be an issue in MSBuild where the same file can get included more than once in the list of files to get copied, and (b) these files will typically be read-only in a Team Build since they are retrieved from version control (and not checked out).&amp;nbsp;&amp;nbsp;The workarounds for the issue depend on the version of Team Build (and MSBuild) you are using.&lt;/p&gt; &lt;h2&gt;Team Build 2005 / MSBuild 2.0&lt;/h2&gt; &lt;p&gt;There are two approaches to fixing the issue in Team Build 2005 / MSBuild 2.0 - removing the duplicate entries from the items copied or removing the read-only bit from the files before they are copied.&amp;nbsp; &lt;/p&gt; &lt;p&gt;For the first possibility, two suggestions for fixing the involved targets (from Microsoft.Common.targets) can be found in an MSBuild forum thread &lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1631035&amp;amp;SiteID=1"&gt;here&lt;/a&gt;.&amp;nbsp; The trick in using these is that you'll need to either (a) modify Microsoft.Common.targets in place, or (b) override the relevant targets in each of your project (e.g. *.csproj) files.&amp;nbsp; Modifying Microsoft.Common.targets in place is not a great idea, since you'll need to do so on every build machine, your changes will get wiped out on upgrade, etc.&amp;nbsp; Overriding the targets in each project is annoying as well, since it can potentially require modification of &lt;em&gt;lots&lt;/em&gt; of project files.&lt;/p&gt; &lt;p&gt;The second possibility, then, may be a bit easier.&amp;nbsp; For example, the following target override in your TfsBuild.proj file should work in most cases:&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;AfterGet&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;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;"&lt;span style="color: rgb(0,0,255)"&gt;attrib -r *.* /S&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt; &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;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;$(SolutionRoot)&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;This logic simply turns off the read-only bit on every file downloaded from version control.&amp;nbsp; If the only files you copy are *.png files, you can change the file mask for the attrib command to speed things up a bit, etc.&amp;nbsp; If you are doing an incremental get, you may need to reset the read-only bit at the end of the build&amp;nbsp;or at the beginning of the next build&amp;nbsp;- 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;"&lt;span style="color: rgb(0,0,255)"&gt;BeforeGet&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;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;"&lt;span style="color: rgb(0,0,255)"&gt;attrib +r *.* /S&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt; &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;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;$(SolutionRoot)&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;h2&gt;Team Build 2008 / MSBuild 3.5&lt;/h2&gt;
&lt;p&gt;In MSBuild 3.5, an &lt;em&gt;OverwriteReadOnlyFiles&lt;/em&gt; property was added that can be set to true to allow Copy tasks involved in the build process to overwrite read-only files in cases like the one outlined here.&amp;nbsp; As such, a third workaround is possible in Team Build 2008 / MSBuild 3.5.&amp;nbsp; Note that this workaround will only work for projects that use&amp;nbsp;the 3.5 version of Microsoft.Common.targets -&amp;nbsp;because of the &lt;a href="http://blogs.msdn.com/msbuild/archive/2006/11/03/msbuild-orcas-and-multi-targeting.aspx"&gt;multi-targeting feature&lt;/a&gt; available in MSBuild, this will&amp;nbsp;not necessarily be every project built by Team Build 2008.&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;To set the &lt;em&gt;OverwriteReadOnlyFiles &lt;/em&gt;property to true globally, you can either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add the text "/p:OverwriteReadOnlyFiles=true" to TfsBuild.rsp for your build definition, or 
&lt;li&gt;Add the following property group to TfsBuild.proj for your build definition.&lt;/li&gt;&lt;/ul&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;CustomPropertiesForBuild&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;gt;&lt;/span&gt;OverwriteReadOnlyFiles=true&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;
&lt;/span&gt;&lt;/pre&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5605289" width="1" height="1"&gt;</description></item><item><title>Running Unit Tests for Individual Configurations with Team Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/19/running-unit-tests-for-individual-configurations-with-team-build.aspx</link><pubDate>Fri, 19 Oct 2007 19:04:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5525502</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5525502</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/19/running-unit-tests-for-individual-configurations-with-team-build.aspx#comments</comments><description>&lt;p&gt;The default behavior of Team Build when running unit tests is to run them for each configuration defined for the build.&amp;nbsp; That is, when you specify configurations for &lt;em&gt;compilation&lt;/em&gt; (e.g. Debug|Any CPU and Release|Any CPU) you are also specifying them for &lt;em&gt;tests&lt;/em&gt;.&amp;nbsp; This is true of both VS TFS Build 2005 and VS TFS Build 2008 (Orcas).&lt;/p&gt; &lt;p&gt;This may not always be desirable - for example, you may want to compile both Debug and Release configurations, but only run unit tests for Release.&amp;nbsp; This sort of behavior is possible within both versions of Team Build, but requires some slightly different modifications in each case.&lt;/p&gt; &lt;h2&gt;VS TFS Build 2005&lt;/h2&gt; &lt;p&gt;In 2005, you will need to do something we don't typically recommend - override one of the &lt;em&gt;CoreXX&lt;/em&gt; targets.&amp;nbsp; The reason we don't typically recommend this is that it is likely to break when you upgrade to newer versions of Team Build.&amp;nbsp; And indeed - the change I will be outlining here &lt;em&gt;will&lt;/em&gt; break if and when you upgrade to VS TFS Build 2008.&amp;nbsp; Unfortunately, it's the only method I've come up with for doing this sort of thing, so when you're ready to upgrade just come back to this post and follow the method given for VS TFS Build 2008 instead...&lt;/p&gt; &lt;p&gt;This is the declaration of the CoreTest target in Microsoft.TeamFoundation.Build.targets:&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CoreTest"&lt;/span&gt;
          &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '$(RunTest)'=='true' "&lt;/span&gt;
          &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="$(CoreTestDependsOn)"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MakeDir&lt;/span&gt; &lt;span class="attr"&gt;Directories&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TestResultsRoot)"&lt;/span&gt;
             &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;="!Exists('$(TestResultsRoot)')"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="$(MSBuildProjectFile)"&lt;/span&gt;
             &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="RunTestWithConfiguration"&lt;/span&gt;
             &lt;span class="attr"&gt;Properties&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildNumber=$(BuildNumber);Platform=%(ConfigurationToBuild.PlatformToBuild);Flavor=%(ConfigurationToBuild.FlavorToBuild);IsDesktopBuild=$(IsDesktopBuild)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;The important bit is the MSBuild task invocation - it &lt;a href="http://msdn2.microsoft.com/en-us/library/ms171473(VS.80).aspx"&gt;batches&lt;/a&gt; over the ConfigurationToBuild item group and calls back into TfsBuild.proj (on the RunTestWithConfiguration target) for each unique combination of PlatformToBuild and FlavorToBuild.&amp;nbsp; That is, it runs tests for each configuration!&lt;/p&gt;
&lt;p&gt;To modify this behavior, you'll need to modify the target so that it only calls back into TfsBuild.proj for the desired configurations.&amp;nbsp; For example, if you only want to run tests for Release|Any CPU, you could do:&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CoreTest"&lt;/span&gt;
          &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '$(RunTest)'=='true' "&lt;/span&gt;
          &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="$(CoreTestDependsOn)"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MakeDir&lt;/span&gt; &lt;span class="attr"&gt;Directories&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TestResultsRoot)"&lt;/span&gt;
             &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;="!Exists('$(TestResultsRoot)')"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="$(MSBuildProjectFile)"&lt;/span&gt;
             &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="RunTestWithConfiguration"&lt;/span&gt;
             &lt;span class="attr"&gt;Properties&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildNumber=$(BuildNumber);Platform=Any CPU;Flavor=Release;IsDesktopBuild=$(IsDesktopBuild)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;If you want to run tests for all Release configuration, you could do:&lt;/p&gt;&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="CoreTest"&lt;/span&gt;
          &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '$(RunTest)'=='true' "&lt;/span&gt;
          &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;="$(CoreTestDependsOn)"&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MakeDir&lt;/span&gt; &lt;span class="attr"&gt;Directories&lt;/span&gt;&lt;span class="kwrd"&gt;="$(TestResultsRoot)"&lt;/span&gt;
             &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;="!Exists('$(TestResultsRoot)')"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;="$(MSBuildProjectFile)"&lt;/span&gt;
             &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '%(ConfigurationToBuild.FlavorToBuild)' == 'Release' "&lt;/span&gt;
             &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;="RunTestWithConfiguration"&lt;/span&gt;
             &lt;span class="attr"&gt;Properties&lt;/span&gt;&lt;span class="kwrd"&gt;="BuildNumber=$(BuildNumber);Platform=%(ConfigurationToBuild.PlatformToBuild);Flavor=%(ConfigurationToBuild.FlavorToBuild);IsDesktopBuild=$(IsDesktopBuild)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;And so forth.&amp;nbsp; Note that you should make these modifications in your TfsBuild.proj file &lt;em&gt;after&lt;/em&gt; the &amp;lt;Import&amp;gt; of Microsoft.TeamFoundation.Build.targets rather than modifying the targets file itself - this way the changes will only impact your build definition and not &lt;em&gt;all&lt;/em&gt; build definitions that execute on the build machine.&lt;/p&gt;
&lt;h2&gt;VS TFS Build 2008&lt;/h2&gt;
&lt;p&gt;In 2008, more extensibility points (targets designed to be overridden) have been added to the build script, including the Before- and AfterTestConfiguration targets, which execute before and after tests are executed for a particular configuration.&amp;nbsp; The simplest thing to do, then, in VS TFS Build 2008, is just to specify a different set of tests to be run for each configuration.&amp;nbsp; In particular, we can empty out the list of metadata files (and/or test containers) for each configuration where unit tests should not be run.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;="BeforeTestConfiguration"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=" '$(Configuration)' != 'Release' "&lt;/span&gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MetadataFile&lt;/span&gt; &lt;span class="attr"&gt;Remove&lt;/span&gt;&lt;span class="kwrd"&gt;="@(MetadataFile)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;TestContainer&lt;/span&gt; &lt;span class="attr"&gt;Remove&lt;/span&gt;&lt;span class="kwrd"&gt;="@(TestContainer)"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Note that this is only possible because MSBuild added support for &lt;em&gt;removing&lt;/em&gt; items from item groups in MSBuild 3.5 - in MSBuild 2.0 you could only &lt;em&gt;add&lt;/em&gt; to item groups, you could never take anything out.&amp;nbsp; Note also that we no longer need to use batching in the condition - the Before- and AfterTestConfiguration targets (and the Before- and AfterCompileConfiguration targets) are executed once per combination of Platform and Flavor (Configuration), and the properties $(Platform) and $(Configuration) can be used to retrieve the &lt;em&gt;current&lt;/em&gt; values.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5525502" width="1" height="1"&gt;</description></item><item><title>Using the SetBuildProperties Task to Update the Log Location for a Build</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/16/using-the-setbuildproperties-task-to-update-the-log-location-for-a-build.aspx</link><pubDate>Tue, 16 Oct 2007 16:08:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5470799</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5470799</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/16/using-the-setbuildproperties-task-to-update-the-log-location-for-a-build.aspx#comments</comments><description>&lt;p&gt;One of the new tasks available in Team Build Orcas (VS 2008) is the SetBuildProperties task.&amp;nbsp; This task allows you to modify any of the settable properties of a BuildDetail object directly from you MSBuild script (TfsBuild.proj).&amp;nbsp; The settable properties include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;BuildNumber.&amp;nbsp; This is often displayed in the GUI as &lt;em&gt;Build Name&lt;/em&gt;.&lt;/li&gt; &lt;li&gt;CompilationStatus.&amp;nbsp; A string representation of the BuildPhaseStatus value for the compilation phase of the build.&amp;nbsp; Valid values include "Failed", "Succeeded", and "Unknown".&lt;/li&gt; &lt;li&gt;DropLocation.&amp;nbsp; The location of the build outputs - typically a UNC path.&lt;/li&gt; &lt;li&gt;LabelName.&amp;nbsp; The name of the version control label generated for the build.&lt;/li&gt; &lt;li&gt;LogLocation.&amp;nbsp; The location of the log file for the build - typically a file called BuildLog.txt at the DropLocation.&lt;/li&gt; &lt;li&gt;Quality.&amp;nbsp; The quality of the build.&lt;/li&gt; &lt;li&gt;SourceGetVersion.&amp;nbsp; The version specifier used to retrieve source files for the build.&lt;/li&gt; &lt;li&gt;Status.&amp;nbsp; A string representation of the BuildStatus value for the overall status of the build.&amp;nbsp; Valid values include "InProgress", "Succeeded", "PartiallySucceeded", "Failed", "Stopped", and "NotStarted".&lt;/li&gt; &lt;li&gt;TestStatus.&amp;nbsp; A string representation of the BuildPhaseStatus value for the testing phase of the build.&amp;nbsp; Valid values include "Failed", "Succeeded", and "Unknown".&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Using the task is pretty simple - just specify the TeamFoundationServerUrl and BuildUri that identify the BuildDetail to be modified and set the desired properties to their new values.&amp;nbsp; For example, to set the log location for a build to a URL, rather than the typical UNC path, you might do 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;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;AfterDropBuild&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;SetBuildProperties&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;                        &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;LogLocation&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;=&lt;/span&gt;"&lt;span style="color: rgb(0,0,255)"&gt;http://www.myurl.com/BuildOutput/BuildNumber_20071016/BuildLog.htm&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;After this change, the link to the log file in the build report for this build will show the new URL, rather than the default UNC path.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5470799" width="1" height="1"&gt;</description></item><item><title>Fancy New Command-Line Options For MSBuild</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/02/fancy-new-command-line-options-for-msbuild.aspx</link><pubDate>Tue, 02 Oct 2007 18:38:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5244095</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=5244095</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/10/02/fancy-new-command-line-options-for-msbuild.aspx#comments</comments><description>&lt;p&gt;A while back I had a &lt;a href="http://blogs.msdn.com/aaronhallberg/archive/2007/05/03/tfsbuild-rsp-and-logging-verbosity-in-orcas.aspx"&gt;post&lt;/a&gt; on the modified command-line options for file logging in MSBuild in&amp;nbsp;the 3.5 .NET Framework.&amp;nbsp; The MSBuild team has since added some cool new command-line options here that will be available in the RTM version of VS 2008 (which will include the 3.5 .NET Framework).&amp;nbsp; In particular, you can now:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Generate logs that contain just the errors or warnings for the build.&amp;nbsp; &lt;/li&gt; &lt;li&gt;Attach multiple file loggers (up to 10, in fact).&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;For the former, you can do something like:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;/flp:errorsonly&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;-or-&lt;/p&gt; &lt;p&gt;&lt;strong&gt;/flp:warningsonly&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;For the latter, you can do something like:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;/flp1:logfile=normal.txt;verbosity=normal /flp2:logfile=diagnostic.txt;verbosity=diagnostic&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Putting the two together, if you wanted to generate three logfiles for each of your Team Build builds - the standard one (BuildLog.txt) containing the normal verbosity output, one containing just errors, and one containing just warnings, you could add the following to your TfsBuild.rsp file:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;/flp:verbosity=normal /flp1:errorsonly;logfile=BuildLog.err /flp2:warningsonly;logfile=BuildLog.wrn&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;One other fancy new feature the MSBuild team&amp;nbsp;has added is the ability to specify&amp;nbsp;&lt;strong&gt;/maxcpucount&lt;/strong&gt; (or just &lt;strong&gt;/m&lt;/strong&gt;) on its own, rather than with an explicit maximum number of concurrent nodes to be used for the build.&amp;nbsp; Under the covers, MSBuild will determine the number of CPUs available on the build machine and use this number of nodes.&amp;nbsp; Unfortunately, this feature was added a bit too late in the game for support to be explicitly added to Team Build.&amp;nbsp; That is, the normal mechanism for enabling multi-process support in Team Build is to set the &lt;em&gt;MaxProcesses&lt;/em&gt; key in the TfsBuildService.exe.config file on your build machine to the value that should be passed into MSBuild via the &lt;strong&gt;/m&lt;/strong&gt; option - this value must be explicitly set to some integer value, however.&amp;nbsp; To take advantage of this feature, just skip this normal approach and add &lt;strong&gt;/m&lt;/strong&gt; to your TfsBuild.rsp file - the "empty" option will override the standard option and your build will use a number of concurrent nodes corresponding to the number of CPUs available on the build machine.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5244095" width="1" height="1"&gt;</description></item><item><title>Running Tests With Team Build Orcas</title><link>http://blogs.msdn.com/b/aaronhallberg/archive/2007/09/12/running-tests-with-team-build-orcas.aspx</link><pubDate>Wed, 12 Sep 2007 15:52:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4879288</guid><dc:creator>aaronhallberg</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/aaronhallberg/rsscomments.aspx?WeblogPostID=4879288</wfw:commentRss><comments>http://blogs.msdn.com/b/aaronhallberg/archive/2007/09/12/running-tests-with-team-build-orcas.aspx#comments</comments><description>&lt;p&gt;The Orcas Beta 2 ReadMe contains (or should contain - let me know if it doesn't!) the following text:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;On build machines with Visual Studio 2005 installed, running tests may fail with the following message:&amp;nbsp; “Failed to load tests from '&amp;lt;assembly&amp;gt;': Microsoft.VisualStudio.TestTools.Exceptions.EqtDataException: UTA059: The test DLL '&amp;lt;assembly&amp;gt;' was built using Visual Studio 2005, and cannot be run. To resolve this issue please rebuild the test DLL using the current version of Visual Studio.”&amp;nbsp; To work around this issue, it will be necessary to use the Visual Studio 2005 version of the TestToolsTask for the affected build definitions.&amp;nbsp; This can be done by setting two properties within TfsBuild.proj as follows:  &lt;p&gt;&amp;nbsp; &amp;lt;PropertyGroup&amp;gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;V8TestToolsTask&amp;gt;true&amp;lt;/V8TestToolsTask&amp;gt;  &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;MSTestRefPath&amp;gt;$(ProgramFiles)\Microsoft Visual Studio 8\Common7\IDE\PrivateAssemblies&amp;lt;/MSTestRefPath&amp;gt;  &lt;p&gt;&amp;nbsp; &amp;lt;/PropertyGroup&amp;gt;  &lt;p&gt;The value for MSTestRefPath may need to be adjusted, depending on the install location of Visual Studio 2005.&amp;nbsp; This property group can come at any point in TfsBuild.proj &lt;i&gt;after&lt;/i&gt; the import of Microsoft.TeamFoundation.Build.targets.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It should be noted that this issue has been resolved for Orcas RTM, at which point the Visual Studio 2008 TestToolsTask will be able to run unit tests compiled using Visual Studio 2005 &lt;em&gt;or&lt;/em&gt; Visual Studio 2008 and this workaround will no longer be necessary.&amp;nbsp; What exactly is going on here, you might ask?&lt;/p&gt; &lt;p&gt;The basic issue is that the Visual Studio 2005 TestToolsTask and earlier versions (up to Beta 2) of the Visual Studio 2008 TestToolsTask were built on the same framework used for MSTest.exe.&amp;nbsp; As such, using the VS 2005 TestToolsTask was essentially equivalent to using VS 2005 MSTest.exe, and using the VS 2008 TestToolsTask was essentially equivalent to running VS 2008 MSTest.exe.&amp;nbsp; As a result, the VS 2005 TestToolsTask can only run unit tests compiled against the VS 2005 unit test framework, and the VS 2008 TestToolsTask can only run unit tests compiled against the VS 2008 unit test framework.&lt;/p&gt; &lt;p&gt;To fix the issue for Orcas RTM, the TestToolsTask was redesigned from the ground up as an inheritor of &lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.build.utilities.tooltask(vs.90).aspx"&gt;Microsoft.Build.Utilities.ToolTask&lt;/a&gt;, which "...provides functionality for a task that wraps a command line tool".&amp;nbsp; Internally, the task will attempt to detect the version of the unit test framework that the unit tests it is running were compiled against and will locate and invoke the appropriate version of MSTest.exe.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Of course, as a side effect of this change, the properties of ToolTask are available to users of TestToolsTask.&amp;nbsp; Interesting properties include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ExitCode.&amp;nbsp; This output property gives the exit code returned by MSTest.exe.&lt;/li&gt; &lt;li&gt;StandardErrorImportance / StandardOutputImportance.&amp;nbsp; These properties control the &lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.build.framework.messageimportance.aspx"&gt;importance&lt;/a&gt; with which standard error and standard output are redirected to the attached MSBuild loggers.&amp;nbsp; In combination with the &lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.build.framework.loggerverbosity.aspx"&gt;logger verbosity&lt;/a&gt; used for the various loggers, this will control whether these messages show up in your build logs.&lt;/li&gt; &lt;li&gt;ToolPath.&amp;nbsp; This property allows you to explicitly control the path where MSTest.exe is executed from.&amp;nbsp; If the default logic of locating the appropriate version of MSTest.exe doesn't work for you, this path will give you a workaround to explicitly specify the location of MSTest.exe.&lt;/li&gt; &lt;li&gt;ToolExe.&amp;nbsp; This property allows to to explicitly control the &lt;em&gt;name&lt;/em&gt; of the executed tool.&amp;nbsp; You probably won't ever need to set this, but if for some reason you have a tool that uses the same command-line syntax as MSTest.exe but is called something else, this property would give you the ability to use it...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;-Aaron&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4879288" width="1" height="1"&gt;</description></item></channel></rss>
