<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Aaron Hallberg</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/aaronhallberg/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/feed.xml</link>
    <description>Team Build (Build Automation) - Visual Studio North Carolina</description>
    <lastBuildDate>Tue, 16 Apr 2019 04:26:35 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Lots of Good Blog Content</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/lots-of-good-blog-content</link>
      <pubDate>Tue, 22 Dec 2009 13:34:00 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2009/12/22/lots-of-good-blog-content/</guid>
      <description><![CDATA[I've been neglecting my blogging duties for the past many months while we finish off the bulk of Dev...]]></description>
      <content:encoded><![CDATA[<P>I've been neglecting my blogging duties for the past many months while we finish off the bulk of Dev 10 - sorry about that.&nbsp; In the meantime, lots of other folks have posted lots of good TFS Build 2010 content, including:</P>
<UL>
<LI><A href="http://blogs.msdn.com/jimlamb"><FONT color=#0000cc>Jim Lamb</FONT></A>'s post on <A href="http://blogs.msdn.com/jimlamb/archive/2009/11/18/how-to-create-a-custom-workflow-activity-for-tfs-build-2010.aspx"><FONT color=#0000cc>creating a custom workflow activity for TFS Build 2010</FONT></A>.&nbsp; 
<LI><A href="http://blogs.msdn.com/patcarna/"><FONT color=#0000cc>Patrick Carnahan</FONT></A>'s posts on customizing build information (<A href="http://blogs.msdn.com/patcarna/archive/2009/11/17/tfs-2010-customizing-build-information.aspx"><FONT color=#0000cc>part 1</FONT></A>, <A href="http://blogs.msdn.com/patcarna/archive/2009/11/19/tfs-2010-customizing-build-information-part-2.aspx"><FONT color=#0000cc>part 2</FONT></A>), and an <A href="http://blogs.msdn.com/patcarna/archive/2009/12/04/introduction-to-windows-workflow-4-0.aspx"><FONT color=#0000cc>Introduction to Windows Workflow 4.0</FONT></A>. 
<LI><A href="http://blogs.msdn.com/adamroot/"><FONT color=#0000cc>Adam Root</FONT></A>'s workaround for a <A href="http://blogs.msdn.com/adamroot/archive/2009/12/10/building-vs-2008-unit-test-projects-in-msbuild-4-0-beta-2.aspx"><FONT color=#0000cc>Beta 2 bug</FONT></A> where 9.0 test projects end up with a bogus reference to the 4.0 framework and fail with a BadImageFormatException. 
<LI><A href="http://blogs.msdn.com/jpricket"><FONT color=#0000cc>Jason Prickett</FONT></A>'s posts on new <A href="http://blogs.msdn.com/jpricket/archive/2009/12/09/tfs-2010-how-about-those-build-delete-options.aspx"><FONT color=#0000cc>build deletion options</FONT></A>, <A href="http://blogs.msdn.com/jpricket/archive/2009/12/21/tfs-2010-displaying-custom-build-information-in-visual-studio.aspx"><FONT color=#0000cc>displaying custom build information</FONT></A> in Visual Studio, and <A href="http://blogs.msdn.com/jpricket/archive/2009/12/22/tfs2010-changing-the-way-build-information-is-displayed.aspx"><FONT color=#0000cc>modifying the default display of build information</FONT></A> in Visual Studio. </LI></UL>
<P>There should be lots more good stuff coming on all these blogs, and on my own, over the next weeks and months.&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Writing Custom Activities for TFS Build 2010 (Beta 1)</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/writing-custom-activities-for-tfs-build-2010-beta-1</link>
      <pubDate>Mon, 01 Jun 2009 10:49:30 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2009/06/01/writing-custom-activities-for-tfs-build-2010-beta-1/</guid>
      <description><![CDATA[With TFS Build 2010 (Beta 1), we've changed the build orchestration language from MSBuild to Windows...]]></description>
      <content:encoded><![CDATA[<p>With <a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx">TFS Build 2010 (Beta 1)</a>, we've changed the build orchestration language from MSBuild to Windows Workflow Foundation (WF).&#160; As such, you now have a new option for adding custom logic to your build proces - custom WF activities.&#160; I've gotten a couple of requests for a blog post with an example, best practices, and so forth, so here goes.</p>  <p>There are four ways (that I know of, at least) to author a custom WF activity - using the WF Designer / XML Editor and <em>composing</em> your custom activity in XAML; <em>composing </em>your custom activity in code; writing a custom <em><a href="http://msdn.microsoft.com/en-us/library/system.activities.codeactivity(VS.100).aspx">CodeActivity</a></em>; or writing a custom <em><a href="http://msdn.microsoft.com/en-us/library/system.activities.nativeactivity(VS.100).aspx">NativeActivity</a></em>.&#160; This list is more or lest organized by degree of difficulty, and more or less by preference as well.&#160; </p>  <p>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:</p>  <ol>   <li>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? </li>    <li>Composed activities are by their nature <em>cancellable </em>by the workflow runtime, meaning that builds running your custom activity will be easy to stop cleanly. </li>    <li>Composed activities can participate in workflow tracking, meaning that their internal progress can be easily tracked as they execute.&#160; (If you don't <em>want</em> their progress to be tracked when running in a build, you can turn this behavior off using Microsoft.TeamFoundation.Build.Workflow.Tracking.ActivityTrackingAttribute.) </li>    <li>It's comparatively easy, at least once you get the hang of it. </li> </ol>  <p>I'll be tackling these approaches in this post, and the <em>CodeActivity</em> and <em>NativeActivity</em> approaches in a subsequent post.&#160; The activity I'll be writing takes in a server path to a script file and a <a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.workspace.aspx">Workspace</a> object (along with a couple of other optional parameters), executes the script, and returns the exit code.&#160; The assumption, then, is that this activity will be used in a build process at some point <em>after</em> the workspace for the build has been set up and <em>after</em> that workspace has been synched.&#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.&#160; </p>  <p>To write my activity, I created a new WF <em>ActivityLibrary</em> 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.&#160; I then added the various arguments I wanted my activity to have using the <em>Arguments </em>flyout in the WF designer, dragged and dropped a Sequence activity and the two TFS Build activities I needed, set the appropriate properties, etc.&#160; Here's what it looks like in the Beta 1 WF Designer:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_2.jpg" original-url="http://blogs.msdn.com/blogfiles/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_2.jpg"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InvokeScript" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_thumb.jpg" original-url="http://blogs.msdn.com/blogfiles/aaronhallberg/WindowsLiveWriter/WritingCustomActivitiesforTFSBuild2010Be_860E/InvokeScript_thumb.jpg" width="235" height="244" /></a> </p>  <p>And here's the XAML:</p>  <pre class="code"><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Activity</span><span style="color: rgb(255,0,0)"> mc</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">Ignorable</span><span style="color: rgb(0,0,255)">=&quot;&quot;</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">Class</span><span style="color: rgb(0,0,255)">=&quot;ActivityLibrary1.InvokeScript&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">=&quot;http://schemas.microsoft.com/netfx/2009/xaml/activities/design&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span>__<span style="color: rgb(255,0,0)">InvokeScript</span><span style="color: rgb(0,0,255)">=&quot;clr-namespace:ActivityLibrary1;&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">mc</span><span style="color: rgb(0,0,255)">=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">mtbwa</span><span style="color: rgb(0,0,255)">=&quot;clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">mtvc</span><span style="color: rgb(0,0,255)">=&quot;clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">p</span><span style="color: rgb(0,0,255)">=&quot;http://schemas.microsoft.com/netfx/2009/xaml/activities&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">sad</span><span style="color: rgb(0,0,255)">=&quot;clr-namespace:System.Activities.Debugger;assembly=System.Activities&quot;</span><span style="color: rgb(255,0,0)"> xmlns</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">x</span><span style="color: rgb(0,0,255)">=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&gt;
</span><span style="color: rgb(163,21,21)">  </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Members</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Property</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;Arguments&quot;</span><span style="color: rgb(255,0,0)"> Type</span><span style="color: rgb(0,0,255)">=&quot;p:InArgument(x:String)&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Property</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;Script&quot;</span><span style="color: rgb(255,0,0)"> Type</span><span style="color: rgb(0,0,255)">=&quot;p:InArgument(x:String)&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Property</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;WorkingDirectory&quot;</span><span style="color: rgb(255,0,0)"> Type</span><span style="color: rgb(0,0,255)">=&quot;p:InArgument(x:String)&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Property</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;Workspace&quot;</span><span style="color: rgb(255,0,0)"> Type</span><span style="color: rgb(0,0,255)">=&quot;p:InArgument(mtvc:Workspace)&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Property</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;ExitCode&quot;</span><span style="color: rgb(255,0,0)"> Type</span><span style="color: rgb(0,0,255)">=&quot;p:OutArgument(x:Int32)&quot; /&gt;
</span><span style="color: rgb(163,21,21)">  </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Members</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">  </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Sequence</span><span style="color: rgb(255,0,0)"> DisplayName</span><span style="color: rgb(0,0,255)">=&quot;Invoke Script From Source Control&quot;</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Sequence.Variables</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Variable</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;localScriptPath&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Sequence.Variables</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ConvertWorkspaceItem</span><span style="color: rgb(255,0,0)"> DisplayName</span><span style="color: rgb(0,0,255)">=&quot;Convert Server Path to Local Path&quot;</span><span style="color: rgb(255,0,0)"> Input</span><span style="color: rgb(0,0,255)">=&quot;[Script]&quot;</span><span style="color: rgb(255,0,0)"> Result</span><span style="color: rgb(0,0,255)">=&quot;[localScriptPath]&quot;</span><span style="color: rgb(255,0,0)"> Workspace</span><span style="color: rgb(0,0,255)">=&quot;[Workspace]&quot; /&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess</span><span style="color: rgb(255,0,0)"> Arguments</span><span style="color: rgb(0,0,255)">=&quot;[String.Format(&amp;quot;/c &amp;quot;&amp;quot;{0}&amp;quot;&amp;quot; {1}&amp;quot;, localScriptPath, Arguments)]&quot;</span><span style="color: rgb(255,0,0)"> DisplayName</span><span style="color: rgb(0,0,255)">=&quot;Invoke the Script&quot;</span><span style="color: rgb(255,0,0)"> FileName</span><span style="color: rgb(0,0,255)">=&quot;[&amp;quot;cmd.exe&amp;quot;]&quot;</span><span style="color: rgb(255,0,0)"> Result</span><span style="color: rgb(0,0,255)">=&quot;[ExitCode]&quot;</span><span style="color: rgb(255,0,0)"> WorkingDirectory</span><span style="color: rgb(0,0,255)">=&quot;[WorkingDirectory]&quot;&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.BeforeExecute</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">            </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Variable</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;commandLine&quot; /&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">WriteBuildMessage</span><span style="color: rgb(255,0,0)"> Message</span><span style="color: rgb(0,0,255)">=&quot;[commandLine]&quot; /&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.BeforeExecute</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.ErrorDataReceived</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">            </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Variable</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;errorData&quot; /&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">WriteBuildError</span><span style="color: rgb(255,0,0)"> Message</span><span style="color: rgb(0,0,255)">=&quot;[errorData]&quot; /&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.ErrorDataReceived</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.OutputDataReceived</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">            </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Variable</span><span style="color: rgb(255,0,0)"> x</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(255,0,0)">TypeArguments</span><span style="color: rgb(0,0,255)">=&quot;x:String&quot;</span><span style="color: rgb(255,0,0)"> Name</span><span style="color: rgb(0,0,255)">=&quot;outputData&quot; /&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction.Argument</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">          </span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">WriteBuildMessage</span><span style="color: rgb(255,0,0)"> Importance</span><span style="color: rgb(0,0,255)">=&quot;Normal&quot;</span><span style="color: rgb(255,0,0)"> Message</span><span style="color: rgb(0,0,255)">=&quot;[outputData]&quot; /&gt;
</span><span style="color: rgb(163,21,21)">        </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">ActivityAction</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">      </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess.OutputDataReceived</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">    </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">mtbwa</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">InvokeProcess</span><span style="color: rgb(0,0,255)">&gt;
</span><span style="color: rgb(163,21,21)">  </span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Sequence</span><span style="color: rgb(0,0,255)">&gt;
&lt;/</span><span style="color: rgb(163,21,21)">p</span><span style="color: rgb(0,0,255)">:</span><span style="color: rgb(163,21,21)">Activity</span><span style="color: rgb(0,0,255)">&gt;</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p>You might notice that the various <a href="http://msdn.microsoft.com/en-us/library/system.activities.activityaction(VS.100).aspx">ActivityActions</a> 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 <em>InvokeProcess</em> activity for Beta 1, so for this activity I had to &quot;drop to XAML&quot; and edit the XML directly.&#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.&#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).</p>

<p>As mentioned above, activities can be composed either in xaml or in code.&#160; To write a composed activity in code, you'll derive from <a href="http://msdn.microsoft.com/en-us/library/system.activities.activity(VS.100).aspx">System.Activities.Activity</a>, or <a href="http://msdn.microsoft.com/en-us/library/dd466009(VS.100).aspx">System.Activities.Activity&lt;T&gt;</a>, add whatever arguments and so forth you need, and then override the <em>CreateBody</em> method to return your composed implementation.&#160; Here's a second version of my InvokeScript activity, written in C# code:</p>

<pre class="code"><span style="color: rgb(0,0,255)">using</span> System;
<span style="color: rgb(0,0,255)">using</span> System.Activities;
<span style="color: rgb(0,0,255)">using</span> System.Activities.Statements;
<span style="color: rgb(0,0,255)">using</span> System.ComponentModel;
<span style="color: rgb(0,0,255)">using</span> Microsoft.TeamFoundation.Build.Workflow.Activities;
<span style="color: rgb(0,0,255)">using</span> Microsoft.TeamFoundation.VersionControl.Client;

<span style="color: rgb(0,0,255)">namespace</span> ActivityLibrary1
{
    <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">sealed</span> <span style="color: rgb(0,0,255)">class</span> <span style="color: rgb(43,145,175)">InvokeScript2</span> : Activity&lt;<span style="color: rgb(43,145,175)">Int32</span>&gt;
    {
        [Browsable(<span style="color: rgb(0,0,255)">true</span>)]
        [DefaultValue(<span style="color: rgb(0,0,255)">null</span>)]
        <span style="color: rgb(0,0,255)">public</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt; Arguments { <span style="color: rgb(0,0,255)">get</span>; <span style="color: rgb(0,0,255)">set</span>; }

        [Browsable(<span style="color: rgb(0,0,255)">true</span>)]
        [DefaultValue(<span style="color: rgb(0,0,255)">null</span>)]
        <span style="color: rgb(0,0,255)">public</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt; Script { <span style="color: rgb(0,0,255)">get</span>; <span style="color: rgb(0,0,255)">set</span>; }

        [Browsable(<span style="color: rgb(0,0,255)">true</span>)]
        [DefaultValue(<span style="color: rgb(0,0,255)">null</span>)]
        <span style="color: rgb(0,0,255)">public</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt; WorkingDirectory { <span style="color: rgb(0,0,255)">get</span>; <span style="color: rgb(0,0,255)">set</span>; }

        [Browsable(<span style="color: rgb(0,0,255)">true</span>)]
        [DefaultValue(<span style="color: rgb(0,0,255)">null</span>)]
        <span style="color: rgb(0,0,255)">public</span> InArgument&lt;Workspace&gt; Workspace { <span style="color: rgb(0,0,255)">get</span>; <span style="color: rgb(0,0,255)">set</span>; }

        <span style="color: rgb(0,0,255)">protected</span> <span style="color: rgb(0,0,255)">override</span> WorkflowElement CreateBody()
        {
            Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt; localScriptPath = <span style="color: rgb(0,0,255)">new</span> Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt;();
            Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt; commandLine = <span style="color: rgb(0,0,255)">new</span> Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt;();
            Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt; outputData = <span style="color: rgb(0,0,255)">new</span> Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt;();
            Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt; errorData = <span style="color: rgb(0,0,255)">new</span> Variable&lt;<span style="color: rgb(43,145,175)">String</span>&gt;();

            <span style="color: rgb(0,0,255)">return</span> <span style="color: rgb(0,0,255)">new</span> Sequence
            {
                Variables = 
                {
                    localScriptPath
                },
                Activities =
                {
                    <span style="color: rgb(0,0,255)">new</span> ConvertWorkspaceItem
                    {
                        Input = <span style="color: rgb(0,0,255)">new</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt;(env =&gt; <span style="color: rgb(0,0,255)">this</span>.Script.Get(env)),
                        Workspace = <span style="color: rgb(0,0,255)">new</span> InArgument&lt;Workspace&gt;(env =&gt; <span style="color: rgb(0,0,255)">this</span>.Workspace.Get(env)),
                        Result = localScriptPath
                    },
                    <span style="color: rgb(0,0,255)">new</span> InvokeProcess
                    {
                        FileName = <span style="color: rgb(0,0,255)">new</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt;(env =&gt; <span style="color: rgb(163,21,21)">&quot;cmd.exe&quot;</span>),
                        Arguments = <span style="color: rgb(0,0,255)">new</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt;(env =&gt; <span style="color: rgb(43,145,175)">String</span>.Format(<span style="color: rgb(163,21,21)">&quot;/c \&quot;{0}\&quot; {1}&quot;</span>, localScriptPath.Get(env), Arguments.Get(env))),
                        WorkingDirectory = <span style="color: rgb(0,0,255)">new</span> InArgument&lt;<span style="color: rgb(43,145,175)">String</span>&gt;(env =&gt; <span style="color: rgb(0,0,255)">this</span>.WorkingDirectory.Get(env)),
                        Result = <span style="color: rgb(0,0,255)">new</span> OutArgument&lt;<span style="color: rgb(0,0,255)">int</span>&gt;(env =&gt; <span style="color: rgb(0,0,255)">this</span>.Result.Get(env)),
                        BeforeExecute = <span style="color: rgb(0,0,255)">new</span> ActivityAction&lt;<span style="color: rgb(43,145,175)">String</span>&gt;
                        {
                            Argument = commandLine,
                            Handler = <span style="color: rgb(0,0,255)">new</span> WriteBuildMessage
                            {
                                Message = commandLine
                            },
                        },
                        OutputDataReceived = <span style="color: rgb(0,0,255)">new</span> ActivityAction&lt;<span style="color: rgb(43,145,175)">String</span>&gt;
                        {
                            Argument = outputData,
                            Handler = <span style="color: rgb(0,0,255)">new</span> WriteBuildMessage
                            {
                                Message = outputData
                            },
                        },
                        ErrorDataReceived = <span style="color: rgb(0,0,255)">new</span> ActivityAction&lt;<span style="color: rgb(43,145,175)">String</span>&gt;
                        {
                            Argument = errorData,
                            Handler = <span style="color: rgb(0,0,255)">new</span> WriteBuildError
                            {
                                Message = errorData
                            },
                        },
                    },
                },
            };
        }
    }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>The primary difference between this version and the XAML version is that here I've elevated the single output argument (ExitCode) to the <em>return</em> value of the activity - hence it derives from Activity&lt;Int32&gt;.&#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 <a href="http://msdn.microsoft.com/en-us/library/system.activities.outargument(VS.100).aspx">OutArgument</a> (but this is not, so far as I know, possible when writing an activity in XAML).&#160; </p>]]></content:encoded>
    </item>
    <item>
      <title>TargetsNotLogged Hotfix Available</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/targetsnotlogged-hotfix-available</link>
      <pubDate>Fri, 30 Jan 2009 11:14:22 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2009/01/30/targetsnotlogged-hotfix-available/</guid>
      <description><![CDATA[I did a post a while back on a change in TFS Build SP1 which reduced build log noise by cutting out...]]></description>
      <content:encoded><![CDATA[<p>I did a <a href="http://blogs.msdn.com/aaronhallberg/archive/2008/05/05/orcas-sp1-tfs-build-changes.aspx">post</a> 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 &quot;Project 'project' is building project 'dependent project' for target(s) 'GetNativePath'&quot;, and so forth).&#160; Unfortunately, as noted on the TFS Build <a href="http://social.msdn.microsoft.com/forums/en-US/tfsbuild/thread/49106d4e-74ff-45fa-a744-6a21fa35e081/">forums</a> and elsewhere, the fix in SP1 didn't actually fix the problem, at least not completely.&#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 <em>first</em> time a particular project-to-project reference was evaluated.&#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.</p>  <p>A hotfix is finally available that will address the remaining parts of the problem - it can be downloaded <a href="http://code.msdn.microsoft.com/KB958845">here</a>.&#160; Note that this hotfix assumes that you have already installed SP1 on your build machine, so make sure to install SP1 and <em>then</em> the hotfix if you are currently running TFS Build 2008 RTM bits.&#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 <em>dramatic </em>effect on build time (each of those build steps corresponds to a server call made during the build).</p>]]></content:encoded>
    </item>
    <item>
      <title>Calling Custom Targets in Team Build, Part 3</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/calling-custom-targets-in-team-build-part-3</link>
      <pubDate>Tue, 30 Dec 2008 16:13:15 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/12/30/calling-custom-targets-in-team-build-part-3/</guid>
      <description><![CDATA[I've done a couple of posts now on calling custom targets during a Team Build build - this one...]]></description>
      <content:encoded><![CDATA[<p>I've done a couple of posts now on calling custom targets during a Team Build build - <a href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/07/calling-custom-targets-within-team-build.aspx">this one</a> focused on calling custom targets in the solution/project being built, and <a href="http://blogs.msdn.com/aaronhallberg/archive/2008/02/08/calling-custom-targets-within-team-build-part-2.aspx">this one</a> focused on calling custom targets in your TfsBuild.proj file itself before/after the compilation of individual solutions or configurations.&#160; In the past week I've gotten two questions on whether one can call custom targets before/after the compilation of individual <em>projects</em> within a solution.&#160; That is, whether Microsoft.TeamFoundation.Build.targets supports Before/AfterCompileProject targets in the same way it supports Before/AfterCompileConfiguration and Before/AfterCompileSolution ones.</p>  <p>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.&#160; There are three potential methods (that I could think of) for doing this sort of thing:</p>  <ol>   <li>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.&#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.</li>    <li>You could use a custom MSBuild &quot;traversal&quot; project in place of your solution, and insert your custom logic into this traversal project before/after the individual projects are compiled.&#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.&#160; The disadvantage to this approach is that you then have two files to maintain in parallel - your solution and your custom traversal project.&#160; One possible workaround here would be to write a custom MSBuild task to generate this traversal project automatically as part of the build.&#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.&#160; </li>    <li>Finally, you could put the before/after compile logic into the individual projects themselves, either directly or via in imported *.targets file.&#160; Individual .NET projects have their own Before/AfterBuild extensibility targets that could be utilized for this purpose.&#160; </li> </ol>  <p>This last option strikes me as the best one when including simplicity in the calculation...&#160; The targets file would look something like this:</p>  <pre class="code"><span style="color: rgb(0,0,255)">&lt;?</span><span style="color: rgb(163,21,21)">xml</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">version</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">1.0</span>&quot;<span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">encoding</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">utf-8</span>&quot;<span style="color: rgb(0,0,255)">?&gt;
&lt;</span><span style="color: rgb(163,21,21)">Project</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">xmlns</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">http://schemas.microsoft.com/developer/msbuild/2003</span>&quot;<span style="color: rgb(0,0,255)">&gt;

  &lt;!--</span><span style="color: rgb(0,128,0)"> Only execute this custom logic when the project is building under Team Build. </span><span style="color: rgb(0,0,255)">--&gt;
  &lt;</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Name</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">AfterBuild</span>&quot;<span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Condition</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)"> '$(TeamBuildConstants)' == '_TEAM_BUILD_' </span>&quot;<span style="color: rgb(0,0,255)">&gt;
    &lt;!--</span><span style="color: rgb(0,128,0)"> Put your custom logic here. </span><span style="color: rgb(0,0,255)">--&gt;
  &lt;/</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)">&gt;
  
&lt;/</span><span style="color: rgb(163,21,21)">Project</span><span style="color: rgb(0,0,255)">&gt;</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p>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.&#160; For example, the end of a *.csproj file might look like:</p>

<pre class="code"><span style="color: rgb(0,0,255)">  &lt;</span><span style="color: rgb(163,21,21)">Import</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Project</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(MSBuildToolsPath)\Microsoft.CSharp.targets</span>&quot;<span style="color: rgb(0,0,255)"> /&gt;
  &lt;</span><span style="color: rgb(163,21,21)">Import</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Project</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">..\..\TeamBuildTypes\SomeDefinition\AfterCompileProject.targets</span>&quot;<span style="color: rgb(0,0,255)">/&gt;
</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(163,21,21)">Project</span><span style="color: rgb(0,0,255)">&gt;</span></pre>]]></content:encoded>
    </item>
    <item>
      <title>The CompilationOutputs Item Group</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/the-compilationoutputs-item-group</link>
      <pubDate>Fri, 08 Aug 2008 13:49:29 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/08/08/the-compilationoutputs-item-group/</guid>
      <description><![CDATA[I've mentioned the CompilationOutputs item group we added in TFS 2008 before in passing (see this...]]></description>
      <content:encoded><![CDATA[<p>I've mentioned the CompilationOutputs item group we added in TFS 2008 before in passing (see this <a href="http://blogs.msdn.com/aaronhallberg/archive/2007/07/12/team-build-devenv-task.aspx">post</a>, for example), but never given it the attention it deserves...&#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.&#160; Furthermore, it includes metadata that allows you to distinguish the outputs for each platform/configuration pair and for each individual solution.&#160; For example, given solutions Foo.sln and Bar.sln and configurations x86|Debug and x86|Retail, the following target:</p>  <pre class="code"><span style="color: rgb(0,0,255)">  &lt;</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Name</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">AfterCompile</span>&quot;<span style="color: rgb(0,0,255)">&gt;
    &lt;</span><span style="color: rgb(163,21,21)">Message</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Text</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">%(CompilationOutputs.Solution) built %(Identity) for %(Platform)|%(Configuration).</span>&quot; /<span style="color: rgb(0,0,255)">&gt; </span>
<span style="color: rgb(0,0,255)">  &lt;/</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)">&gt;
</span></pre>

<p>...might produce the following output:</p>

<pre class="code">  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.</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>Of course, producing that output is not particularly exciting.&#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).&#160; I'm sure users of Team Build will come up with lots of other creative uses for this item group as well.</p>]]></content:encoded>
    </item>
    <item>
      <title>A Minimal TFSBuild.Proj File</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/a-minimal-tfsbuild-proj-file</link>
      <pubDate>Mon, 28 Jul 2008 10:31:29 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/07/28/a-minimal-tfsbuild-proj-file/</guid>
      <description><![CDATA[A fair number of people seem to want to use Team Build to kick off their own pre-existing build...]]></description>
      <content:encoded><![CDATA[<p>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.&#160; While we don't typically <em>encourage</em> this, enough people want to do it that I figured I should finally post an example.&#160; So - the minimal tfsbuild.proj file that will kick off your custom build script would look something like this:</p>  <pre class="code"><span style="color: rgb(0,0,255)">&lt;?</span><span style="color: rgb(163,21,21)">xml</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">version</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">1.0</span>&quot;<span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">encoding</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">utf-8</span>&quot;<span style="color: rgb(0,0,255)">?&gt;
&lt;</span><span style="color: rgb(163,21,21)">Project</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">xmlns</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">http://schemas.microsoft.com/developer/msbuild/2003</span>&quot;<span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">ToolsVersion</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">3.5</span>&quot;<span style="color: rgb(0,0,255)">&gt;
  &lt;</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Name</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">EndToEndIteration</span>&quot;<span style="color: rgb(0,0,255)">&gt;
    &lt;</span><span style="color: rgb(163,21,21)">Exec</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Command</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">SomeScript.cmd</span>&quot;<span style="color: rgb(0,0,255)"> /&gt;
  &lt;/</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)">&gt;
&lt;/</span><span style="color: rgb(163,21,21)">Project</span><span style="color: rgb(0,0,255)">&gt;
</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p>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.</p>

<p>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.&#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 <em>import</em> of Microsoft.TeamFoundation.Build.targets) alone.</p>]]></content:encoded>
    </item>
    <item>
      <title>Associating changesets and Work Items Since the Last Successful Build</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/associating-changesets-and-work-items-since-the-last-successful-build</link>
      <pubDate>Wed, 16 Jul 2008 09:40:32 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/07/16/associating-changesets-and-work-items-since-the-last-successful-build/</guid>
      <description><![CDATA[We got a forum post the other day on whether changesets and work items could be associated since the...]]></description>
      <content:encoded><![CDATA[<p>We got a forum post the other day on whether changesets and work items could be associated since the last <em>Successful</em> build.&#160; Some of you may be thinking &quot;Isn't that how it already works?&quot;&#160; Actually, it's not <em>quite</em> how it works.&#160; Changesets and Work Items are, by default, associated since the last &quot;good&quot; build, where &quot;good&quot; means compilation and tests succeeded, but something else may have gone wrong.&#160; That is, the last &quot;good&quot; build may well be marked <em>Partially</em> <em>Succeeded</em> and not <em>Succeeded</em>.</p>  <p>I started responding to the forum post, and then figured it would make a good blog post instead.&#160; (Of course, I've posted a link to this post in the forums...)</p>  <p>So - to modify the default behavior and associate changesets and work items only since the last <em>successful</em> build, you'll need to do three things:</p>  <ol>   <li>Skip the default logic to associate changesets and work items.&#160; This is pretty simple - just set the SkipGetChangesetsAndUpdateWorkItems property to true. </li>    <li>Write a custom task to <em>find</em> the last successful build and return its label. </li>    <li>Call this custom task and then call the GenCheckinNotesUpdateWorkItems task with its output. </li> </ol>  <p>Lucky for you, I've already written the custom task (or at least a simple version of it).&#160; Here is the source for it:</p>  <pre class="code"><span style="color: rgb(0,0,255)">using</span> System;
<span style="color: rgb(0,0,255)">using</span> Microsoft.Build.Framework;
<span style="color: rgb(0,0,255)">using</span> Microsoft.TeamFoundation.Client;
<span style="color: rgb(0,0,255)">using</span> Microsoft.TeamFoundation.Build.Client;

<span style="color: rgb(0,0,255)">namespace</span> BlogProjects
{
    <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">class</span> <span style="color: rgb(43,145,175)">GetLastSuccessfulBuildLabel</span> : <span style="color: rgb(43,145,175)">ITask
</span>    {
<span style="color: rgb(0,0,255)">        #region</span> Properties

        [<span style="color: rgb(43,145,175)">Required</span>]
        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">String</span> BuildDefinitionName
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_buildDefinitionName;
            }
            <span style="color: rgb(0,0,255)">set
</span>            {
                m_buildDefinitionName = <span style="color: rgb(0,0,255)">value</span>;
            }
        }

        [<span style="color: rgb(43,145,175)">Output</span>]
        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">String</span> LastSuccessfulBuildLabel
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_lastSuccessfulBuildLabel;
            }
        }

        [<span style="color: rgb(43,145,175)">Required</span>]
        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">String</span> TeamFoundationServerUrl
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_teamFoundationServerUrl;
            }
            <span style="color: rgb(0,0,255)">set
</span>            {
                m_teamFoundationServerUrl = <span style="color: rgb(0,0,255)">value</span>;
            }
        }

        [<span style="color: rgb(43,145,175)">Required</span>]
        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">String</span> TeamProject
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_teamProject;
            }
            <span style="color: rgb(0,0,255)">set
</span>            {
                m_teamProject = <span style="color: rgb(0,0,255)">value</span>;
            }
        }

<span style="color: rgb(0,0,255)">        #endregion

        #region</span> ITask Members

        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(0,0,255)">bool</span> Execute()
        {
            <span style="color: rgb(43,145,175)">TeamFoundationServer</span> tfs = <span style="color: rgb(43,145,175)">TeamFoundationServerFactory</span>.GetServer(TeamFoundationServerUrl);
            <span style="color: rgb(43,145,175)">IBuildServer</span> buildServer = (<span style="color: rgb(43,145,175)">IBuildServer</span>)tfs.GetService(<span style="color: rgb(0,0,255)">typeof</span>(<span style="color: rgb(43,145,175)">IBuildServer</span>));

            <span style="color: rgb(43,145,175)">IBuildDetailSpec</span> spec = buildServer.CreateBuildDetailSpec(TeamProject, BuildDefinitionName);
            spec.MaxBuildsPerDefinition = 1;
            spec.Status = <span style="color: rgb(43,145,175)">BuildStatus</span>.Succeeded;
            spec.QueryOrder = <span style="color: rgb(43,145,175)">BuildQueryOrder</span>.FinishTimeDescending;

            <span style="color: rgb(43,145,175)">IBuildQueryResult</span> queryResult = buildServer.QueryBuilds(spec);

            <span style="color: rgb(0,0,255)">if</span> (queryResult.Builds.Length &gt; 0)
            {
                m_lastSuccessfulBuildLabel = queryResult.Builds[0].LabelName;
            }

            <span style="color: rgb(0,0,255)">return</span> <span style="color: rgb(0,0,255)">true</span>;
        }

        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">IBuildEngine</span> BuildEngine
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_buildEngine;
            }
            <span style="color: rgb(0,0,255)">set
</span>            {
                m_buildEngine = <span style="color: rgb(0,0,255)">value</span>;
            }
        }

        <span style="color: rgb(0,0,255)">public</span> <span style="color: rgb(43,145,175)">ITaskHost</span> HostObject
        {
            <span style="color: rgb(0,0,255)">get
</span>            {
                <span style="color: rgb(0,0,255)">return</span> m_taskHost;
            }
            <span style="color: rgb(0,0,255)">set
</span>            {
                m_taskHost = <span style="color: rgb(0,0,255)">value</span>;
            }
        }

<span style="color: rgb(0,0,255)">        #endregion

        #region</span> Private Members

        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">IBuildEngine</span> m_buildEngine;
        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">ITaskHost</span> m_taskHost;
        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">String</span> m_teamFoundationServerUrl;
        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">String</span> m_buildDefinitionName;
        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">String</span> m_teamProject;
        <span style="color: rgb(0,0,255)">private</span> <span style="color: rgb(43,145,175)">String</span> m_lastSuccessfulBuildLabel;

<span style="color: rgb(0,0,255)">        #endregion
</span>    }
}</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>Note the fancy querying that is possible with an IBuildDetailSpec - pretty cool...&#160; </p>

<p>Calling the custom task should be similarly simple.&#160; Something like the following should do the trick:</p>

<pre class="code"><span style="color: rgb(0,0,255)">  &lt;</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">Name</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">BeforeGetChangesetsAndUpdateWorkItems</span>&quot;<span style="color: rgb(0,0,255)">&gt;

    &lt;</span><span style="color: rgb(163,21,21)">GetLastSuccessfulBuildLabel</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">TeamFoundationServerUrl</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(TeamFoundationServerUrl)</span>&quot;
<span style="color: rgb(0,0,255)">                                 </span><span style="color: rgb(255,0,0)">TeamProject</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(TeamProject)</span>&quot;<span style="color: rgb(0,0,255)"> 
                                 </span><span style="color: rgb(255,0,0)">BuildDefinitionName</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(BuildDefinitionName)</span>&quot;<span style="color: rgb(0,0,255)">&gt;
      &lt;</span><span style="color: rgb(163,21,21)">Output</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">TaskParameter</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">LastSuccessfulBuildLabel</span>&quot;<span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">PropertyName</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">LastSuccessfulBuildLabel</span>&quot;<span style="color: rgb(0,0,255)"> /&gt;
    &lt;/</span><span style="color: rgb(163,21,21)">GetLastSuccessfulBuildLabel</span><span style="color: rgb(0,0,255)">&gt;

    &lt;</span><span style="color: rgb(163,21,21)">GenCheckinNotesUpdateWorkItems</span><span style="color: rgb(0,0,255)"> </span><span style="color: rgb(255,0,0)">TeamFoundationServerUrl</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(TeamFoundationServerUrl)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">BuildUri</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(BuildUri)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">BuildNumber</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(BuildNumber)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">CurrentLabel</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(LabelName)@$(LabelScope)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">LastLabel</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(LastSuccessfulBuildLabel)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">UpdateWorkItems</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">$(UpdateAssociatedWorkItems)</span>&quot;
<span style="color: rgb(0,0,255)">                                    </span><span style="color: rgb(255,0,0)">ContinueOnError</span><span style="color: rgb(0,0,255)">=</span>&quot;<span style="color: rgb(0,0,255)">true</span>&quot;<span style="color: rgb(0,0,255)"> /&gt;

  &lt;/</span><span style="color: rgb(163,21,21)">Target</span><span style="color: rgb(0,0,255)">&gt;
</span></pre>
<a href="http://11011.net/software/vspaste"></a>

<p>Hope this helps!</p>

<p><strong>UPDATE</strong>: My original post had a typo - the property <em>SkipGetChangesetsAndUpdateWorkItems</em> was missing its <em>And</em>.&#160; My apologies to anyone who banged their head against the wall trying to figure out why it wasn't working!</p>]]></content:encoded>
    </item>
    <item>
      <title>Attaching Custom Data to a Build</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/attaching-custom-data-to-a-build</link>
      <pubDate>Tue, 27 May 2008 08:11:43 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/05/27/attaching-custom-data-to-a-build/</guid>
      <description><![CDATA[In Orcas, we introduced a generic information storage for builds - internally this is used for all...]]></description>
      <content:encoded><![CDATA[<p>In Orcas, we introduced a generic information storage for builds - internally this is used for all build steps, associated changesets/workitems, etc.&#160; You can use it to attach arbitrary data to a build (and later retrieve it).&#160; Here are a couple of quick code snippets to illustrate these two cases. </p>  <p>To attach a single name/value pair to a build, you would do something like this:</p>  <pre class="code">        <span style="color: rgb(43,145,175)">TeamFoundationServer</span> tfs = <span style="color: rgb(43,145,175)">TeamFoundationServerFactory</span>.GetServer(tfsUrl);
        <span style="color: rgb(43,145,175)">IBuildServer</span> buildServer = (<span style="color: rgb(43,145,175)">IBuildServer</span>)tfs.GetService(<span style="color: rgb(0,0,255)">typeof</span>(<span style="color: rgb(43,145,175)">IBuildServer</span>));
        <span style="color: rgb(43,145,175)">IBuildDetail</span> buildDetail = buildServer.GetBuild(buildUri);

        <span style="color: rgb(43,145,175)">IBuildInformationNode</span> node = buildDetail.Information.CreateNode();

        node.Type = <span style="color: rgb(163,21,21)">&quot;MyCompany.Custom&quot;</span>;
        node.Fields[<span style="color: rgb(163,21,21)">&quot;key&quot;</span>] = <span style="color: rgb(163,21,21)">&quot;value&quot;</span>;

        buildDetail.Information.Save();</pre>

<p>To retrieve the same name/value pair from the build, you would do something like this:</p>

<pre class="code">        <span style="color: rgb(43,145,175)">TeamFoundationServer</span> tfs = <span style="color: rgb(43,145,175)">TeamFoundationServerFactory</span>.GetServer(tfsUrl);
        <span style="color: rgb(43,145,175)">IBuildServer</span> buildServer = (<span style="color: rgb(43,145,175)">IBuildServer</span>)tfs.GetService(<span style="color: rgb(0,0,255)">typeof</span>(<span style="color: rgb(43,145,175)">IBuildServer</span>));
        <span style="color: rgb(43,145,175)">IBuildDetail</span> buildDetail = buildServer.GetBuild(buildUri);

        <span style="color: rgb(43,145,175)">List</span>&lt;<span style="color: rgb(43,145,175)">IBuildInformationNode</span>&gt; nodes = buildDetail.Information.GetNodesByType(<span style="color: rgb(163,21,21)">&quot;MyCompany.Custom&quot;</span>);

        <span style="color: rgb(0,0,255)">if</span> (nodes.Count &gt; 0)
        {
            <span style="color: rgb(0,0,255)">foreach</span> (<span style="color: rgb(43,145,175)">IBuildInformationNode</span> node <span style="color: rgb(0,0,255)">in</span> nodes)
            {
                <span style="color: rgb(43,145,175)">String</span> value = node[<span style="color: rgb(163,21,21)">&quot;key&quot;</span>];

                <span style="color: rgb(0,128,0)">// Do something...
</span>            }
        }</pre>
<a href="http://11011.net/software/vspaste"></a>

<p>Note that the information node storage is hierarchical, so you can get a lot fancier than this if you want/need to!&#160; Note that full documentation of the Orcas TFS Build Object Model can be found <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;DisplayLang=en">here</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Orcas RTM Object Model Documentation</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/orcas-rtm-object-model-documentation</link>
      <pubDate>Tue, 27 May 2008 07:55:02 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/05/27/orcas-rtm-object-model-documentation/</guid>
      <description><![CDATA[The official Orcas RTM OM documentation was posted a while ago, and I neglected to blog about...]]></description>
      <content:encoded><![CDATA[<p>The official Orcas RTM OM documentation was posted a while ago, and I neglected to blog about it!&#160; It's available here: <a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;DisplayLang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;DisplayLang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=6466b53d-d80b-4c31-8f5c-dfb5d32e9411&amp;DisplayLang=en</a>.&#160; </p>  <p>Make sure to follow the instructions for viewing it after downloading:</p>  <p><b>Method 1</b></p>  <ol>   <li>Double-click the .chm file. </li>    <li>In the <b>Open File-Security Warning</b> dialog box, clear the <b>Always ask before opening this file</b> check box. </li>    <li>Click <b>Open</b>. </li> </ol> <b>Method 2</b>  <ol>   <li>Right-click the CHM file, and then click <b>Properties</b>. </li>    <li>Click <b>Unblock</b>. </li>    <li>Double-click the .chm file to open the file. </li> </ol>  <p>I'm yanking the <a href="http://blogs.msdn.com/aaronhallberg/archive/2007/08/14/orcas-beta-2-object-model-documentation.aspx">Beta 2 documentation</a> now that this has been posted...</p>]]></content:encoded>
    </item>
    <item>
      <title>Tech*Ed 2008</title>
      <link>https://docs.microsoft.com/archive/blogs/aaronhallberg/teched-2008</link>
      <pubDate>Mon, 19 May 2008 09:37:45 GMT</pubDate>
      <dc:creator><![CDATA[Garry Trinder]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/aaronhallberg/2008/05/19/teched-2008/</guid>
      <description><![CDATA[If you are planning on attending Tech*Ed Developers in sunny Orlando this year, I'll be manning the...]]></description>
      <content:encoded><![CDATA[<p>If you are planning on attending <a href="http://www.microsoft.com/events/teched2008/developer/default.mspx">Tech*Ed Developers</a> 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.&#160; Please stop by and say hello, ask some questions, provide some feedback, etc. </p>  <p>Other folks at the booth will include my fellow Visual Studio North Carolina folks <a href="http://blogs.msdn.com/edhintz/">Ed Hintz</a> (a man of many hats, including Dev Lead for the Version Control Client and Team System Web Access teams and <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=00DFCD6E-4902-4F42-8E9F-859119C60D6A&amp;displaylang=en">Power Tools</a> guru), and <a href="http://blogs.msdn.com/crathjen/">Chris Rathjen</a> (tester extraordinaire on the Admin &amp; Ops team).</p>  <p>Hope to see lots of you there!</p>]]></content:encoded>
    </item>
  </channel>
</rss>