<?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>Random Musings of Jeremy Jameson : TFS</title><link>http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx</link><description>Tags: TFS</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Building SharePoint WSPs with Team Foundation Build</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/18/building-sharepoint-wsps-with-team-foundation-build.aspx</link><pubDate>Wed, 18 Nov 2009 13:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9924271</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9924271.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9924271</wfw:commentRss><description>&lt;P&gt;As I noted in my &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/11/18/the-copy-local-bug-in-visual-studio.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/11/18/the-copy-local-bug-in-visual-studio.aspx"&gt;previous post&lt;/A&gt;, I recently discovered that &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx"&gt;my approach for building Web Solution Packages (WSPs)&lt;/A&gt; in Microsoft Office SharePoint Server (MOSS) 2007 isn't compatible with Team Foundation Build.&lt;/P&gt;
&lt;P&gt;I'm actually a little embarrassed to say this, but when I created the original &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/31/introducing-the-dr-dada-approach-to-sharepoint-development.aspx"&gt;"DR.DADA" approach for MOSS 2007&lt;/A&gt; development back on the Agilent Technologies project, we were using Visual SourceSafe -- not Team Foundation Server (TFS) -- and a "manual" build process.&lt;/P&gt;
&lt;P&gt;I'd used VSS and automated builds on other projects before (using NAnt), but never got around to automating our MOSS 2007 builds on the Agilent project because, honestly, there were just too many other higher priority items. Besides, each build only required a couple of minutes of actual human effort because most of the build was scripted.&lt;/P&gt;
&lt;P&gt;Still, an automated daily build (and deployment to DEV) is a &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/26/best-practices-for-scm-and-the-daily-build-process.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/26/best-practices-for-scm-and-the-daily-build-process.aspx"&gt;really, really good thing to have&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;I've been fortunate to be on a few projects since then that have leveraged TFS.&lt;/P&gt;
&lt;P&gt;However, up until about a month ago, I hadn't used Team Foundation Build (outside of the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;Jameson Datacenter&lt;/A&gt;, of course) due to the fact that we are leveraging the extranet TFS instance hosted by Microsoft.&lt;/P&gt;
&lt;P&gt;Note that Microsoft IT makes it very easy for us to provision new TFS projects on either the extranet or one of several internal TFS instances. Configuring builds using Team Foundation Build on one of the intranet TFS instances is very easy (from what I hear), but I strongly prefer working off the extranet TFS instance because then I don't have to VPN into CorpNet in order to have access to source control.&lt;/P&gt;
&lt;P&gt;However, choosing the extranet TFS instance also means we can't configure builds using the out-of-the-box functionality in Team Foundation Server (at least not without setting up a build server on the extranet). Fortunately, I've found a way to schedule "manual" builds that look a lot like automated builds performed using Team Foundation Build.&lt;/P&gt;
&lt;P&gt;So, if you are building SharePoint WSPs -- regardless of whether you use the real Team Foundation Build or my "imitation Team Foundation Build" -- you need a way to build the WSPs without referring to referenced assemblies using relative paths.&lt;/P&gt;
&lt;P&gt;As I first mentioned in my previous post, relative paths work just fine when compiling from within Visual Studio or using MSBuild from the command line. However, they don't work at all when queuing the builds through Team Foundation Build.&lt;/P&gt;
&lt;P&gt;The problem with relative paths is that Team Foundation Build uses a different folder structure when compiling your projects. Specifically, it changes the output folder for all compiled items to be under a new &lt;STRONG&gt;Binaries &lt;/STRONG&gt;folder -- not the location specified in the project settings within Visual Studio.&lt;/P&gt;
&lt;P&gt;In other words, if you refer to a referenced assembly using something like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;..\..\..\CoreServices\bin\%BUILD_CONFIGURATION%\Fabrikam.Demo.CoreServices.dll&lt;/BLOCKQUOTE&gt;
&lt;P&gt;then you will find that this works just fine when building through Visual Studio -- or even when compiling using TFSBuild.proj from the command line (a.k.a. a "Desktop Build"). However, if you then queue the build through Team Foundation Server, you'll find your build fails because the referenced assembly was actually output to a different folder.&lt;/P&gt;
&lt;P&gt;If you dive into the log file for the build, you will find that Team Foundation Build modifies the &lt;STRONG&gt;OutDir &lt;/STRONG&gt;variable and sets it to something like:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;C:\Users\svc-build\AppData\Local\Temp\Demo\Daily Build - Main\Binaries\Debug\&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So the trick to building WSPs with Team Foundation Build is to leverage the &lt;STRONG&gt;OutDir &lt;/STRONG&gt;variable instead of relying on relative paths to referenced assemblies.&lt;/P&gt;
&lt;P&gt;Here is the updated DDF file based on &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/28/sample-walkthrough-of-the-dr-dada-approach-to-sharepoint.aspx"&gt;my earlier sample&lt;/A&gt;:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;;
; This ddf specifies the structure of the .wsp solution cab file.
;
; HACK: OPTION EXPLICIT cannot be used when specifying a variable with the /D option,
; otherwise MakeCAB aborts with an error similar to the following:
;
;        ERROR: Option Explicit and variable not defined: OUT_DIR
;
;.OPTION EXPLICIT    ; Generate errors for undefined variables

.Set CabinetNameTemplate=Fabrikam.Demo.Publishing.wsp

; The following variable must be set when calling MakeCAB (using the /D option)
;.Define OUT_DIR=

.Set DiskDirectoryTemplate=CDROM    ; All cabinets go in a single directory
.Set CompressionType=MSZIP            ; All files are compressed in cabinet files
.Set UniqueFiles=ON
.Set Cabinet=ON
.Set DiskDirectory1=%OUT_DIR%\Package

DeploymentFiles\PackageFiles\manifest.xml

.Set SourceDir=%OUT_DIR%            ; Copy assemblies from %OUT_DIR% folder

Fabrikam.Demo.Publishing.dll
Fabrikam.Demo.CoreServices.dll

.Set SourceDir=                    ; Copy files relative to project folder

.Set DestinationDir=Fabrikam.Demo.Publishing.DefaultSiteConfiguration
DefaultSiteConfiguration\FeatureFiles\Feature.xml

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts
Layouts\FeatureFiles\Feature.xml
Layouts\FeatureFiles\ProvisionedFiles.xml

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\MasterPages
Layouts\MasterPages\FabrikamMinimal.master

;.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\PageLayouts
;Layouts\PageLayouts\MinimalPage.aspx

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\Images
Layouts\Images\FabrikamLogo_32x32.png

.Set DestinationDir=Fabrikam.Demo.Publishing.Layouts\Themes\Theme1
Layouts\Themes\Theme1\BreadcrumbBullet.gif
Layouts\Themes\Theme1\FauxColumn-Fixed-2Col.png
Layouts\Themes\Theme1\FauxColumn-Fixed-3Col.png
Layouts\Themes\Theme1\Fabrikam-Basic.css
Layouts\Themes\Theme1\Fabrikam-Core.css
Layouts\Themes\Theme1\Fabrikam-FixedLayout.css
Layouts\Themes\Theme1\Fabrikam-IE.css
Layouts\Themes\Theme1\Fabrikam-IE6.css
Layouts\Themes\Theme1\Fabrikam-QuirksMode.css
Layouts\Themes\Theme1\Tab-LeftSide.jpg
Layouts\Themes\Theme1\Tab-RightSide.jpg

.Set DestinationDir=ControlTemplates\Fabrikam\Demo\Publishing\Layouts
Layouts\Web\UI\WebControls\GlobalNavigation.ascx
Layouts\Web\UI\WebControls\StyleDeclarations.ascx

.Set DestinationDir=Layouts\Fabrikam
Layouts\MasterPages\FabrikamMinimal.master&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Note how I've replaced the BUILD_CONFIGURATION variable with the OUT_DIR variable. Not surprisingly, the OUT_DIR variable in the DDF is specified similar to how BUILD_CONFIGURATION was previously specified when calling makecab.exe. However, unlike the build configuration the OutDir variable will likely contain spaces as well as a trailing slash (which makecab.exe apparently doesn't like). Therefore we must quote the OutDir variable and append with "." if a trailing slash is found.&lt;/P&gt;
&lt;P&gt;Here is the corresponding update to the project file:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;PropertyGroup&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;BuildDependsOn&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
&lt;/SPAN&gt;      $(BuildDependsOn);
      CreateSharePointSolutionPackage
&lt;SPAN style="COLOR: #0000ff"&gt;    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;BuildDependsOn&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;"$(OutDir)"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Condition&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;HasTrailingSlash($(OutDir))&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;"$(OutDir)."&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;QuotedOutDir&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;PropertyGroup&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
  &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;CreateSharePointSolutionPackage&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Inputs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;@(None);@(Content);$(OutDir)$(TargetFileName);&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Outputs&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;$(ProjectDir)$(OutDir)Package\Fabrikam.Demo.Publishing.wsp&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Message&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;Creating SharePoint solution package...&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; /&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Exec&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;Command&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt;makecab /D OUT_DIR=$(QuotedOutDir) /F &lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;&amp;amp;quot;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;$(ProjectDir)DeploymentFiles\PackageFiles\wsp_structure.ddf&lt;/SPAN&gt;&lt;SPAN style="COLOR: #ff0000"&gt;&amp;amp;quot;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: #0000ff"&gt; /&amp;gt;
  &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;With these changes, the SharePoint WSP is successfully built regardless of whether it is compiled through Visual Studio, from the command line using MSBuild and the TFSBuild.proj file, or as an automated build using a Team Foundation Build server.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9924271" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Simplify/default.aspx">Simplify</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/MOSS+2007/default.aspx">MOSS 2007</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/WSS+v3/default.aspx">WSS v3</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Compiling C++ Projects with Team Foundation Build</title><link>http://blogs.msdn.com/jjameson/archive/2009/11/07/compiling-c-projects-with-team-foundation-build.aspx</link><pubDate>Sat, 07 Nov 2009 16:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919079</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9919079.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9919079</wfw:commentRss><description>&lt;P&gt;As I mentioned in my &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/11/07/using-password-minder-to-manage-your-passwords.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/11/07/using-password-minder-to-manage-your-passwords.aspx"&gt;previous post&lt;/A&gt;, this week I incorporated Password Minder into my "Toolbox" Visual Studio solution that is scheduled to build daily through Team Foundation Server (TFS).&lt;/P&gt;
&lt;P&gt;It's not that I really need daily builds of Password Minder; rather it's just been something on my "TO DO" list for a long time and I finally got around to doing it. Unfortunately, it wasn't without issue.&lt;/P&gt;
&lt;P&gt;In case you are not familiar with Password Minder, it is mostly written in C#, but it includes one C++ project (for the NativeHelpers.dll).&lt;/P&gt;
&lt;P&gt;Thus when I added the Password Minder projects to my "Toolbox" solution, I woke up the next morning to a notification from Team Foundation Server that my build failed. [No, I don't have some sort of alarm that goes off when one of my builds break. By "notification" I am referring to the e-mail message that I found in my inbox when I sat down at the computer.]&lt;/P&gt;
&lt;P&gt;Clicking the build log referenced in the e-mail message, I quickly discovered the following:&lt;/P&gt;
&lt;DIV class=logExcerpt&gt;&lt;SAMP&gt;Using "VCBuild" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Task "VCBuild"&lt;BR&gt;Locating vcbuild.exe: not found at "c:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\..\..\vc\vcpackages\vcbuild.exe".&lt;BR&gt;Locating vcbuild.exe: Visual C++ Express is not installed on this computer.&lt;BR&gt;Locating vcbuild.exe: falling back to the system PATH variable.&lt;BR&gt;C:\Users\svc-build\AppData\Local\Temp\Toolbox\Automated Build - Main\Sources\Source\Toolbox.sln : error MSB3411: Could not load the Visual C++ component "VCBuild.exe". If the component is not installed, either 1) install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5, or 2) install Microsoft Visual Studio 2008.&lt;/SAMP&gt;&lt;/DIV&gt;
&lt;P&gt;That certainly is one of the best error messages I've seen in a long time. It told me exactly what I needed to do to fix the problem. Well, almost...&lt;/P&gt;
&lt;P&gt;Note that DAZZLER (a VM in the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; that is my dedicated build server) does not have the full installation of Visual Studio 2008. Rather it only has the Team Foundation Build install. In keeping with best practices, I try to keep the build server as "clean" as possible. That means no Visual Studio, no SharePoint, etc.&lt;/P&gt;
&lt;P&gt;Following option #1 from the log file, I proceeded to install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5 -- but, of course, I didn't bother to review the ReadMe file that comes with it (at least not at first).&lt;/P&gt;
&lt;P&gt;Consequently, I was greeted with the following error on the next build attempt:&lt;/P&gt;
&lt;DIV class=logExcerpt&gt;&lt;SAMP&gt;c:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets : warning MSB3428: Could not load the Visual C++ component "VCProjectEngine.dll". To fix this, 1) install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5, 2) install Microsoft Visual Studio 2008 or 3) add the location of the component to the system path if it is installed elsewhere. System error code: 126.&lt;BR&gt;c:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets : warning MSB3425: Could not resolve VC project reference "..\NativeHelpers\NativeHelpers.vcproj".&lt;/SAMP&gt;&lt;/DIV&gt;
&lt;P&gt;That's when I discovered the following from the release notes for the SDK:&lt;/P&gt;
&lt;BLOCKQUOTE class=directQuote&gt;
&lt;H4&gt;5.1.1 VCBuild fails to compile or upgrade projects&lt;/H4&gt;
&lt;P&gt;In order for VCBuild to run properly, vcprojectengine.dll needs to be registered. If vcprojectengine.dll is not registered, VCBuild.exe will fail with errors such as:&lt;/P&gt;
&lt;P&gt;On compile: &lt;CODE&gt;warning MSB3422: Failed to retrieve VC project information through the VC project engine object model. System error code: 127.&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;On upgrade: &lt;CODE&gt;Failed to upgrade project file ‘foo.vcproj'. Please make sure the file exists and is not write-protected.&lt;/CODE&gt;&lt;/P&gt;
&lt;P&gt;To workaround this issue, &lt;CODE&gt;vcprojectengine.dll&lt;/CODE&gt; must be manually registered. From a Windows SDK command line window (as administrator in Vista:&lt;/P&gt;
&lt;P&gt;On an X86 machine, run:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;cd %mssdk%\VC\bin
regsvr32 vcprojectengine.dll&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;On an X64 machine, run:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;cd %mssdk%\VC\bin\X64
regsvr32 vcprojectengine.dll&lt;/CODE&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Unfortunately, these instructions aren't quite right -- or at least they didn't work verbatim in my environment. The workaround stated above makes you think there's an environment variable (&lt;CODE&gt;%mssdk%&lt;/CODE&gt;) that refers to the path where the SDK is installed. However, this wasn't configured on DAZZLER.&lt;/P&gt;
&lt;P&gt;Also, I didn't find my copy of VCProjectEngine.dll in an &lt;STRONG&gt;x64 &lt;/STRONG&gt;folder, but rather in an &lt;STRONG&gt;amd64 &lt;/STRONG&gt;folder:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\VCProjectEngine.dll&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I know most of you out there are not doing much (if any) C++ work anymore, but I thought I should share this just in case you need it at some point.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919079" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Recommended Check-In Policies for Team Foundation Server</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/31/recommended-check-in-policies-for-team-foundation-server.aspx</link><pubDate>Sat, 31 Oct 2009 12:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9915639</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9915639.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9915639</wfw:commentRss><description>&lt;P&gt;I love using Team Foundation Server (TFS). There's just an amazing amount of "goodness" for software development that comes out-of-the-box; and there's even more available from Microsoft and other sources in the form of add-ons (many of which are free).&lt;/P&gt;
&lt;P&gt;From a source control perspective, one of my favorite features is check-in policies. Anything that improves the quality of software development with minimal effort is really a "&lt;A href="http://wordnetweb.princeton.edu/perl/webwn?s=no-brainer" mce_href="http://wordnetweb.princeton.edu/perl/webwn?s=no-brainer"&gt;no-brainer&lt;/A&gt;" in my opinion.&lt;/P&gt;
&lt;P&gt;The check-in policies that I prefer to have configured on all TFS projects are listed in the following table.&lt;/P&gt;
&lt;TABLE class=accent1 cellSpacing=0 class="accent1"&gt;
&lt;CAPTION&gt;Recommended TFS Check-In Policies&lt;/CAPTION&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH&gt;Policy Type&lt;/TH&gt;
&lt;TH&gt;Description&lt;/TH&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;Builds&lt;/TD&gt;
&lt;TD&gt;This policy requires that any code changes have been compiled and the last build was successful.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Work Items&lt;/TD&gt;
&lt;TD&gt;This policy requires that one or more work items be associated with every check-in.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Changeset Comments Policy&lt;/TD&gt;
&lt;TD&gt;Reminds users to add meaningful comments to their check-ins.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Code Analysis&lt;/TD&gt;
&lt;TD&gt;This policy requires that Code Analysis is run with a defined set of rules before check-in.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Testing Policy&lt;/TD&gt;
&lt;TD&gt;Ensures that tests from specific test lists are successfully executed before checking in.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;The first two check-in policies are virtually painless and can be applied to any existing project at any time. These policies ship with Visual Studio Team System 2008, and assuming your developers have good software development discipline already, there's absolutely no reason not to enable these policies.&lt;/P&gt;
&lt;P&gt;After all, why would any developer want to check-in code that hasn't been verified to at least compile? Similarly, why would a developer make a code change that isn't specifically related to a work item (even if that work item is simply something like "Refactor X" or "Code cleanup (M5)")?&lt;/P&gt;
&lt;P&gt;However, the last three policies in the table above require a little more effort.&lt;/P&gt;
&lt;P&gt;The Changeset Comments Policy is included in the &lt;A href="http://msdn.microsoft.com/en-us/teamsystem/bb980963.aspx" mce_href="http://msdn.microsoft.com/en-us/teamsystem/bb980963.aspx"&gt;Team Foundation Server Power Tools&lt;/A&gt;, which means that every member of the Development team will need to download and install this in order to use it. (Note that if you don't have the Power Tools installed, you can still override the check-in policy in order to avoid being blocked.)&lt;/P&gt;
&lt;P&gt;The Code Analysis policy can definitely cause a little heartburn for your Development team, depending on how many code analysis rules you enable and whether or not you treat these warnings as errors. I'll talk more about Code Analysis in a separate post.&lt;/P&gt;
&lt;P&gt;The Testing Policy is not one that I consider essential for all projects. For projects in which you have a good set of Build Verification Tests (BVTs) that give you a signficant amount of code coverage and don't take very long to execute, then enabling this policy just makes sense. However, keep in mind that you should definitely be running BVTs as part of your automated build, so if these tests require a substantial amount of time to execute (for example, they require signficant setup or teardown), then forcing developers to run these tests before every check-in could definitely impede their productivity.&lt;/P&gt;
&lt;P&gt;Of course, you can always separate your tests into "quick tests" and "long running tests" like I've mentioned in a previous &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/19/argumentnullexception-with-optional-publishingpage-description-property-with-some-thoughts-on-breaking-the-build-too.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/19/argumentnullexception-with-optional-publishingpage-description-property-with-some-thoughts-on-breaking-the-build-too.aspx"&gt;post&lt;/A&gt;, and consequently only require the "quick tests" to be executed before check-in.&lt;/P&gt;
&lt;P&gt;If you are fortunate enough to be using TFS on your project, I hope you are reaping the benefits of check-in policies.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9915639" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Essential Add-Ins for Team Foundation Server</title><link>http://blogs.msdn.com/jjameson/archive/2009/10/25/essential-add-ins-for-team-foundation-server.aspx</link><pubDate>Sun, 25 Oct 2009 15:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9912619</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9912619.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9912619</wfw:commentRss><description>&lt;P&gt;In a &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/24/diffmerge-a-better-differencing-tool.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/24/diffmerge-a-better-differencing-tool.aspx"&gt;previous post&lt;/A&gt;, I mentioned how I use SourceGear's DiffMerge instead of the out-of-the-box tool that comes with Team Foundation Server (which is also called DiffMerge). If you haven't at least evaluated the SourceGear alternative, I definitely advise you to take a look.&lt;/P&gt;
&lt;P&gt;The other "add-in" for TFS that I consider to be essential is the &lt;A href="http://www.acorns.com.au/projects/vsaddins/" mce_href="http://www.acorns.com.au/projects/vsaddins/"&gt;TFS Quick Search Plugin&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;If you have Web access to your TFS instance (via &lt;A href="http://msdn.microsoft.com/en-us/teamsystem/bb980951.aspx" mce_href="http://msdn.microsoft.com/en-us/teamsystem/bb980951.aspx"&gt;Team System Web Access&lt;/A&gt;), then quickly locating work items by keywords is actually pretty easy. However if you either don't have access to Team System Web Access or you would simply rather prefer to search for a work item without leaving Visual Studio, then the TFS Quick Search Plugin is definitely the way to go.&lt;/P&gt;
&lt;P&gt;Note that it doesn't search all of the fields in all work items, but rather searches the work items currently displayed within Visual Studio. However, if you know a keyword that appears in the title of a work item, this can make it very easy to locate the desired work item.&lt;/P&gt;
&lt;P&gt;I tend to use the TFS Quick Search Plugin a lot for the scenario where I am trying to find a duplicate bug and I remember a couple of keywords in the title of the previous bug. It is certainly much faster than scrolling through a few hundred work items in order to find something, or trying to build a query on-the-fly in order to locate a work item.&lt;/P&gt;
&lt;P&gt;I am really interested to see the improvements in Visual Studio 2010 and Team Foundation Server 2010, but honestly it's probably going to be a while before I'm able to use that in my day-to-day work. Nevertheless, I hope this kind of work item "quick search" comes out-of-the-box in the next release (as well as a better DiffMerge tool). [I did do some hands-on labs back in February that cover the new branching visualization features in TFS 2010, and I have to say that I absolutely love what I've seen so far.]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9912619" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Best Practices for SCM and the Daily Build Process</title><link>http://blogs.msdn.com/jjameson/archive/2009/09/26/best-practices-for-scm-and-the-daily-build-process.aspx</link><pubDate>Sat, 26 Sep 2009 19:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899876</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9899876.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9899876</wfw:commentRss><description>&lt;P&gt;In a previous post, I briefly discussed &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/02/10/branching-strategy-in-team-foundation-server.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/02/10/branching-strategy-in-team-foundation-server.aspx"&gt;a simple branching strategy for Team Foundation Server&lt;/A&gt; (TFS). This was somewhat of a follow-up to another &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx"&gt;post&lt;/A&gt; in which I briefly referenced a great article titled &lt;A href="http://downloads.seapine.com/pub/papers/SCMBranchingModels.pdf" mce_href="http://downloads.seapine.com/pub/papers/SCMBranchingModels.pdf"&gt;The Importance of Branching Models in SCM&lt;/A&gt;. If you haven't read this article, I highly recommend it.&lt;/P&gt;
&lt;P&gt;However, while branching is certainly an important aspect of Software Configuration Management (SCM) -- and perhaps one of the most important aspects -- it's certainly not the only one that warrants discussion. In this post, I want to cover some other best practices for SCM as well as the daily build process.&lt;/P&gt;
&lt;P&gt;For example, if you are using TFS, you know that each TFS project typically has a source control repository as well as a project team site in SharePoint (a.k.a. the "Project Portal"). You also probably know that all SharePoint document libraries can be configured to support versioning similar to TFS source control, and thus allow you to, for example, view an old version of an installation guide stored on the Project Portal. However, just because you &lt;EM&gt;can&lt;/EM&gt; do this doesn't mean that it is &lt;EM&gt;recommended &lt;/EM&gt;as a best practice&lt;EM&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Note that I'm not saying you should not store any documents on the Project Portal, nor am I saying that you should never enable versioning on document libraries in the Project Portal.&lt;/P&gt;
&lt;P&gt;On the contrary, the Project Portal provides a great place to store documents that various project stakeholders need to access from time to time (without going through Visual Studio or TFS Web Access), and I almost always recommend enabling versioning on all document libraries in your SharePoint sites (provided you have plenty of storage on the backend SQL Server, of course).&lt;/P&gt;
&lt;P&gt;Enabling versions on document libraries provides the ability to go back and see who changed a document and when (which is sort of like an "audit trail" on a document). While you could use the SharePoint versioning feature to go "back in time" in order to view the state of a document (e.g. an installation guide) for a particular version or build of your solution, this would obviously involve a good deal of considerable effort based on timestamps.&lt;/P&gt;
&lt;P&gt;A much easier way of correlating a version of a particular document to a particular build of your solution is to actually store the document in source control within TFS. This allows you to quickly retrieve the document version using a changeset number or, more generally, a build label.&lt;/P&gt;
&lt;H5&gt;Build Labels&lt;/H5&gt;
&lt;P&gt;Back in the days of using Visual SourceSafe (VSS) on customer projects, at the beginning of the build process, a label would always be applied to the project in VSS. Since the build label was applied at the top-level project within a branch, it applied to all files in the solution – including the source code, setup files, and automated tests. This ensures that the installation and tests could be repeated for any particular build.&lt;/P&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;While VSS certainly provided the ability to retrieve a project based on a particular timestamp, it definitely wasn't easy (the only way that I was ever to do it was through &lt;A href="http://msdn.microsoft.com/en-us/library/asxkfzy4(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/asxkfzy4(VS.80).aspx"&gt;the SS command line utility&lt;/A&gt;). Thus build labels provided a quick way of getting a snapshot of the code for a particular build.&lt;BR&gt;&lt;BR&gt;With the concept of changesets in TFS -- and the ability to quickly get the code for a specific changeset -- build labels are obviously not as important as they were in VSS. However, regardless of which particular source control system you are using, build labels provide an easy way to identify and retrieve important builds (such as &lt;STRONG&gt;Beta 1&lt;/STRONG&gt;, &lt;STRONG&gt;Beta 2&lt;/STRONG&gt;, &lt;STRONG&gt;RC1&lt;/STRONG&gt;, and &lt;STRONG&gt;v1.0&lt;/STRONG&gt;) or simply specific versions of the solution (e.g. 1.0.57.0).&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;H6&gt;Source Code&lt;/H6&gt;
&lt;P&gt;Applying the build label to the entire solution allows the Development team to obtain all of the source code for a particular build, thereby enabling them to step through the code to debug an issue that may not be reproducible in the latest version of the code.&lt;/P&gt;
&lt;H6&gt;Setup Files&lt;/H6&gt;
&lt;P&gt;In addition to the source code, the files supporting the installation of the solution (such as the install scripts and the installation guide – but not the compiled setup packages) should also stored in the source control system. In this way, the changes to the installation can be tracked from one version to another.&lt;/P&gt;
&lt;H6&gt;Automated Tests&lt;/H6&gt;
&lt;P&gt;Automated tests change as features are added to the solution. Consequently the tests must be matched to a specific build and therefore need to be checked into the source control system (and therefore labeled as part of the correponding build). Automated tests typically include unit tests as well as Build Verification Tests (BVTs).&lt;/P&gt;
&lt;H5&gt;Daily Build Process&lt;/H5&gt;
&lt;P&gt;The build process is a fundamental activity within any software project. In order to ensure success, the build and deployment process needs to conform to a number of basic requirements. If the solution cannot be built directly from its source code then it is not possible to integrate many of the key processes required for successful delivery.&lt;/P&gt;
&lt;P&gt;The following sections describe the steps in the build process and who is responsible for each part of the process:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Check-Ins" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Check-Ins"&gt;Check-Ins&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Automated_Build_Process" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Automated_Build_Process"&gt;Automated Build Process&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Build_Verification_Tests" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Build_Verification_Tests"&gt;Build Verification Tests&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Smoke_Tests" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Smoke_Tests"&gt;Smoke Tests&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Investigating_Failures" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Investigating_Failures"&gt;Investigating Failures&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Build_Hand-off" mce_href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost&amp;amp;sectionid=5034&amp;amp;bpt=1#Build_Hand-off"&gt;Build Hand-off&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;H6&gt;&lt;A title=Check-Ins name=Check-Ins&gt;&lt;/A&gt;Check-Ins&lt;/H6&gt;
&lt;P&gt;All code included in a build must be checked into source control before the build process is initiated. All checked-in code must compile and it is the responsibility of the developer who checks in the code to ensure that the solution builds and all files that are needed to build the solution are checked in.&lt;/P&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Important&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;The source control must not be left in a broken state at any time. If a build breaks, resolving the problem becomes the highest priority.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Tip&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;You can use the &lt;STRONG&gt;Builds &lt;/STRONG&gt;check-in policy for TFS to ensure the solution compiles before a developer is allowed to check-in a changeset.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;Each member of the Development team is responsible for ensuring the following: 
&lt;UL&gt;
&lt;LI&gt;Check-ins must not break functionality in the solution. If a developer checks in a change in their area of the code, he or she must not expect another developer to resolve errors caused by the check-in; either the person checking in the code must fix the dependant code when they check-in or the developer must work with the other developer(s) to coordinate the check-in.&lt;/LI&gt;
&lt;LI&gt;The installation process must also be kept in a functional state at all times. Whenever a developer adds a feature, he or she is responsible for making sure that any setup changes are completed as well. Feature owners are ultimately responsible for the installation and configuration of their features.&lt;/LI&gt;
&lt;LI&gt;The developer is responsible for writing any custom installation actions needed to deploy their feature, for knowing what files need to be deployed on which server, and what permissions the feature needs to run.&lt;/LI&gt;
&lt;LI&gt;The installation of the feature should be completed when the code is checked into source control. The development of any custom installation actions needs to be done in conjunction with the team lead(s), and should not be done in isolation.&lt;/LI&gt;
&lt;LI&gt;Changes to the installation should be checked in to give the team sufficient time to test the changes before the next scheduled build.&lt;/LI&gt;
&lt;LI&gt;Unit tests must pass in the local developer’s environment (LOCAL) before a check-in is performed. If the unit tests are broken because of changes to the feature’s functionality, the developer must resolve the failures -- or reach agreement with the rest of the Development team to disable certain tests until they can be fixed (which should be a rare occurrence).&lt;/LI&gt;&lt;/UL&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Tip&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;You can use the &lt;STRONG&gt;Testing Policy &lt;/STRONG&gt;check-in policy for TFS to ensure that specific unit tests pass before a developer is allowed to check-in a changeset.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If any of the above conditions cannot be met, the code should not be checked into source control.&lt;/P&gt;
&lt;H6&gt;&lt;A title=Automated_Build_Process name=Automated_Build_Process&gt;&lt;/A&gt;Automated Build Process&lt;/H6&gt;
&lt;P&gt;The automated build process should:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Automatically increment the Build Number or Revision portion of the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/04/03/best-practices-for-net-assembly-versioning.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/04/03/best-practices-for-net-assembly-versioning.aspx"&gt;assembly version&lt;/A&gt; (depending on which branch is being built)&lt;/LI&gt;
&lt;LI&gt;Apply a build label (if appropriate)&lt;/LI&gt;
&lt;LI&gt;Retrieve the code from the source control system&lt;/LI&gt;
&lt;LI&gt;Compile the solution&lt;/LI&gt;
&lt;LI&gt;Run any associated unit tests&lt;/LI&gt;
&lt;LI&gt;Copy the build to the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/25/development-and-build-environments.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/25/development-and-build-environments.aspx"&gt;Release Server&lt;/A&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;If an error occurs during the build -- including execution of the unit tests -- the entire process stops. In this event, an email detailing the error should be mailed to the appropriate distribution list. Once the error is fixed, the build can be restarted. Note that the build/revision number should be incremented for the restarted build.&lt;/P&gt;
&lt;H6&gt;&lt;A title=Build_Verification_Tests name=Build_Verification_Tests&gt;&lt;/A&gt;Build Verification Tests&lt;/H6&gt;
&lt;P&gt;Build Verification Tests (BVTs) are a quick, automated test run on the solution to catch defects in the code. The BVTs should cover the major functionality of the solution but are not meant to be a full regression of all the functionality in the solution.&lt;/P&gt;
&lt;P&gt;The time required to run the entire set of BVTs should be on the order of minutes -- not hours. Otherwise the tests become too cumbersome to run on a regular basis. [Note that this guideline obviously depends on the size of your solution and the resources involved. For example, I believe the BVTs used by the Windows team actually run for several hours, due to the size of the code base. However, it is still short enough to repeat on a daily basis.]&lt;/P&gt;
&lt;P&gt;BVTs are owned by the Test team in conjunction with the Development team to verify the build has completed successfully and to catch any regressions that are introduced as a result of changes to the solution. BVTs should be launched immediately after the automated build and deployment process. The BVTs must return an error to indicate if they have succeeded or failed. Only after the BVTs have passed should the build be considered ready for additional testing by the Test team.&lt;/P&gt;
&lt;P&gt;As noted before, BVTs are owned by Test. The Test team should work closely with Development to keep the BVTs in sync with the changes in the solution. By having the BVTs owned by Test, it ensures that there is a knowledge transfer between Development and Test for any changes to the behavior or architecture of the solution.&lt;/P&gt;
&lt;H6&gt;&lt;A title=Smoke_Tests name=Smoke_Tests&gt;&lt;/A&gt;Smoke Tests&lt;/H6&gt;
&lt;P&gt;In order to successfully deploy the solution, automated tests should be written to survey the environments before and after the application has been deployed. The smoke tests should check that the correct components have been installed, the configuration of the solution has been completed correctly, and that the network connectivity between machines is functioning correctly. The smoke tests must result in a clear pass or fail.&lt;/P&gt;
&lt;P&gt;Smoke tests are generally considered to be more exhaustive than BVTs. The key differentiator is that BVTs are intended to identify whether a build is worthy of additional testing. Ideally, a substantial portion of the testing performed by the Test team is automated -- not manual. So whether you refer to your automated tests as BVTs and consider them part of a "smoke test" is really just a matter of semantics.&lt;/P&gt;
&lt;H6&gt;&lt;A title=Investigating_Failures name=Investigating_Failures&gt;&lt;/A&gt;Investigating Failures&lt;/H6&gt;
&lt;P&gt;When a failure is found with the BVTs or automated smoke tests, the Test team should be the first point of contact to ensure that the tests are correct and the failure is valid.&lt;/P&gt;
&lt;H6&gt;&lt;A title=Build_Hand-off name=Build_Hand-off&gt;&lt;/A&gt;Build Hand-off&lt;/H6&gt;
&lt;P&gt;The Release Management team should always lead the deployment of the solution, with Test and Development provided support as necessary.&lt;/P&gt;
&lt;P&gt;Note that the Development team owns the DEV environment. Consequently, developers will often resort to “tweaking” the environment in order to get the solution deployed and operational. However, in order for the solution to be deployed to TEST, the configuration changes made in DEV must either automated as part of the installation or thoroughly documented as part of the installation guide.&lt;/P&gt;
&lt;H5&gt;Troubleshooting Guide&lt;/H5&gt;
&lt;P&gt;When problems are discovered with the deployment of the solution, a troubleshooting guide should be created (or updated) to capture the experience learned in resolving problems in the solution. The troubleshooting guide is not meant to be exhaustive in terms of troubleshooting all aspects of the solution; however it should provide a baseline for developing the operational support documents for maintaining the solution in the Production environment.&lt;/P&gt;
&lt;P&gt;The troubleshooting guide should capture the process and tools used for investigating the problems with the solution and where to look for logs, events, etc. in the system. It should also capture patterns that have been seen in the solution that point toward a particular fault in the system. &lt;/P&gt;
&lt;BLOCKQUOTE class=note&gt;
&lt;DIV class=noteTitle&gt;&lt;STRONG&gt;Tip&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;A SharePoint site -- or even just a simple SharePoint list -- provides an excellent alternative to a Troubleshooting Guide document. Think of this site --or list -- as a simple "&lt;A href="http://support.microsoft.com/" mce_href="http://support.microsoft.com/"&gt;Knowledge Base&lt;/A&gt;" for your solution.&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899876" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Comparing Source Code Branches</title><link>http://blogs.msdn.com/jjameson/archive/2009/09/16/comparing-source-code-branches.aspx</link><pubDate>Wed, 16 Sep 2009 15:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9895837</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9895837.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9895837</wfw:commentRss><description>&lt;P&gt;During the more than three years I spent helping Agilent Technologies migrate their Internet site from their legacy, proprietary platform to Microsoft Office SharePoint Server (MOSS) 2007, we unfortunately never used Team Foundation Server (TFS). Instead, we used Visual SourceSafe (VSS) in combination with a &lt;A href="http://blogs.msdn.com/jjameson/archive/2008/04/01/tfs-lite-for-wss-v2.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2008/04/01/tfs-lite-for-wss-v2.aspx"&gt;"Work Items" list in SharePoint&lt;/A&gt; that I've described in previous posts.&lt;/P&gt;
&lt;P&gt;While I certainly prefer TFS over VSS, sometimes you simply have to concede that you can't have everything you would like on a customer project and move on to actually getting the work done.&lt;/P&gt;
&lt;P&gt;However, just because we used VSS doesn't mean we didn't follow good Software Configuration Management (SCM) principles. For example, as I've &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx"&gt;described in the past&lt;/A&gt;, I insist on using branching right from the start. Thus when I setup the Visual Studio solution for the Agilent project, I created a &lt;STRONG&gt;Main&lt;/STRONG&gt; branch and subsequently created branches for the various releases (e.g. &lt;STRONG&gt;v1.0&lt;/STRONG&gt;, &lt;STRONG&gt;v2.0&lt;/STRONG&gt;, and &lt;STRONG&gt;v3.0&lt;/STRONG&gt;).&lt;/P&gt;
&lt;P&gt;The particular branch that a developer uses would thus depend on whether the changes are for the next major release or a QFE (hotfix) for the version running in Production. For example, after deploying the &lt;A href="http://www.chem.agilent.com/en-US/Support" mce_href="http://www.chem.agilent.com/en-US/Support"&gt;Technical Support site&lt;/A&gt; (i.e. v2.0), we began working on the "General Site" (i.e. v3.0). [Note that in Agilent's terminology, the "General Site" essentially refers to everything outside of Technical Support, the Literature Library, and the Online Store (i.e. the "Buy" tab).]&lt;/P&gt;
&lt;P&gt;However, since we didn't create the &lt;STRONG&gt;v3.0&lt;/STRONG&gt; branch until shortly before the v3.0 release, all v3 ("General Site") development was initially done on the &lt;STRONG&gt;Main&lt;/STRONG&gt; branch -- just like v2 (Tech Support) development was initially done in &lt;STRONG&gt;Main&lt;/STRONG&gt; prior to creating the &lt;STRONG&gt;v2.0 &lt;/STRONG&gt;branch.&lt;/P&gt;
&lt;P&gt;This branching strategy works really well, regardless of which particular SCM system you actually use. The key thing to remember is that all of the changes should eventually make it into the &lt;STRONG&gt;Main&lt;/STRONG&gt; branch (since that branch will eventually be used to create another branch for the next major release).&lt;/P&gt;
&lt;P&gt;The problem with VSS is that while it certainly supports branching, the merging features, um...well, let's just say that they leave a lot to be desired ;-)&lt;/P&gt;
&lt;P&gt;Personally speaking, I've never felt comfortable using the out-of-the-box merging features in VSS, and instead always insisted on merging the changes from one branch to another manually. TFS is obviously years ahead of VSS in terms of branching and merging, but as I said before, sometimes you simply have to deal with what you've got.&lt;/P&gt;
&lt;P&gt;Fortunately, long before the Agilent project, I had previously created my own process that takes a great deal of the "pain" out of manually merging source code. Here is what I came up with.&lt;/P&gt;
&lt;P&gt;In my &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx"&gt;Toolbox&lt;/A&gt;, I have two simple scripts: DiffBranches.cmd and CopyBranch.cmd.&lt;/P&gt;
&lt;P&gt;Here are the contents of DiffBranches.cmd:&lt;/P&gt;
&lt;DIV class=consoleBlock&gt;&lt;PRE&gt;&lt;SAMP&gt;@echo off

setlocal

REM set DIFFTOOL=Windiff.exe
set DIFFTOOL=C:\NotBackedUp\Public\Toolbox\DiffMerge\DiffMerge.exe

set BRANCH1=%1
set BRANCH2=%2

if ("%BRANCH1%") == ("") set BRANCH1=Main

if ("%BRANCH2%") == ("") set BRANCH2=v3.0

call CopyBranch.cmd "%BRANCH1%" "%BRANCH1%_tmp"

call CopyBranch.cmd "%BRANCH2%" "%BRANCH2%_tmp"

"%DIFFTOOL%" "%BRANCH1%_tmp" "%BRANCH2%_tmp"&lt;/SAMP&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;As you can see, there's not much to it. I simply make temporary copies of the two branches (i.e. by copying the branch folder into a new folder appended with "_tmp") and then use my "Diff Tool" to compare the two folders. Originally, I used WinDiff, but once I &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/03/24/diffmerge-a-better-differencing-tool.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/03/24/diffmerge-a-better-differencing-tool.aspx"&gt;discovered DiffMerge&lt;/A&gt;, I quickly switched to using it exclusively for all of my "diff'ing" activities.&lt;/P&gt;
&lt;P&gt;The real "magic" lies in CopyBranch.cmd:&lt;/P&gt;
&lt;DIV class=consoleBlock&gt;&lt;PRE&gt;&lt;SAMP&gt;@echo off

setlocal

set BRANCH1=%1
set BRANCH2=%2

if ("%BRANCH1%") == ("") set BRANCH1=Main

if ("%BRANCH2%") == ("") set BRANCH2="%BRANCH1%_tmp"

robocopy "%BRANCH1%" "%BRANCH2%" /E /MIR /XD bin obj TestResults /XF *.scc *.suo *.user *.vspscc
&lt;/SAMP&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Note that I put the word &lt;EM&gt;magic&lt;/EM&gt; in quotes because it's really not magic at all. When copying a source code branch, I simply use robocopy.exe and specify the following options:&lt;/P&gt;
&lt;TABLE class=accent1 cellSpacing=0 class="accent1"&gt;
&lt;CAPTION&gt;robocoby.exe command-line options used in CopyBranch.cmd&lt;/CAPTION&gt;
&lt;THEAD&gt;
&lt;TR&gt;
&lt;TH&gt;Command-Line Option&lt;/TH&gt;
&lt;TH&gt;Comments&lt;/TH&gt;&lt;/TR&gt;&lt;/THEAD&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;/E&lt;/TD&gt;
&lt;TD&gt;Copy subdirectories, including empty ones&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;/MIR&lt;/TD&gt;
&lt;TD&gt;Mirror the directory tree, thus ensuring that when I subsequently run CopyBranch.cmd, any deleted files from the original branch are removed from the "temporary" copy of the branch)&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;/XD bin obj TestResults&lt;/TD&gt;
&lt;TD&gt;Exclude directories matching the given names/paths, thus skipping the compiled output (i.e. bin and obj) as well as the test results generated by running unit tests from within Visual Studio&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;/XF *.scc *.suo *.user *.vspscc &lt;/TD&gt;
&lt;TD&gt;Exclude files matching the given names/paths/wildcards, thus skipping source code control files (*.scc and *.vspscc), and Visual Studio solution/project user-specific options (i.e. *.suo and *.user)&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;For example, let's suppose that I've checked in some changes to the &lt;STRONG&gt;v3.0 &lt;/STRONG&gt;branch that need to be propagated to the &lt;STRONG&gt;Main &lt;/STRONG&gt;branch. I would open a command prompt and run the following:&lt;/P&gt;
&lt;DIV class=consoleBlock&gt;&lt;PRE&gt;&lt;SAMP&gt;C:\NotBackedUp\Agilent&amp;gt;DiffBranches.cmd v3.0 Main&lt;/SAMP&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;After the two branches are copied to their respective temporary folders, DiffMerge.exe is launched to compare the two branches. Since I exclude many of the directories and files that are &lt;EM&gt;expected&lt;/EM&gt; to differ between the two branches, I can quickly view only the differences that I am interested in. I can even use DiffMerge.exe to apply the changes interactively (checking out the files to be updated beforehand as necessary). This greatly reduces the effort involved in manually merging changes from one branch into another.&lt;/P&gt;
&lt;P&gt;Note that it takes a little bit of time to copy a branch the first time, but this is lightning fast on subsequent runs. Hence why I don't delete the "_tmp" folders after comparing two branches.&lt;/P&gt;
&lt;P&gt;I occasionally use this process even on projects where we've used Team Foundation Server. For example, I sometimes create a new workspace in TFS to represent a "temporary branch" where I want to experiment with some substantial changes to the source code (while I still have pending changes in my main workspace, that I may have shelved but don't want to check-in just yet). Using a little robocopy.exe and DiffMerge.exe, I can more easily compare two branches or workspaces.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9895837" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Expression Web, My MSDN Blog, and (Now) Team Foundation Server</title><link>http://blogs.msdn.com/jjameson/archive/2009/09/12/expression-web-my-msdn-blog-and-now-team-foundation-server.aspx</link><pubDate>Sat, 12 Sep 2009 17:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9894524</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9894524.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9894524</wfw:commentRss><description>&lt;P&gt;In case you haven't picked it up from some of my previous posts, I became somewhat of a "Web standards zealot" back in 2006 while creating a "community site" for a &lt;A href="http://www.metrodenveridc.org/" mce_href="http://www.metrodenveridc.org"&gt;local organization of mental health professionals and attorneys&lt;/A&gt; that help children and their parents through divorce. After reading books like &lt;A href="http://amzn.com/0321303474" mce_href="http://amzn.com/0321303474"&gt;The Zen of CSS Design&lt;/A&gt;, &lt;A href="http://amzn.com/1430219203" mce_href="http://amzn.com/1430219203"&gt;Web Standards Solutions&lt;/A&gt;, and &lt;A href="http://amzn.com/0321509021" mce_href="http://amzn.com/0321509021"&gt;Bulletproof Web Design&lt;/A&gt;, I realized the fundamental concept of &lt;A href="http://en.wikipedia.org/wiki/Web_standards" mce_href="http://en.wikipedia.org/wiki/Web_standards"&gt;Web standards&lt;/A&gt; design closely aligns with my preference of keeping things as simple as possible. Last year, I got a copy of &lt;A href="http://amzn.com/0321410971" mce_href="http://amzn.com/0321410971"&gt;Transcending CSS&lt;/A&gt; and I highly recommend this book as well for anyone responsible for creating Web sites.&lt;/P&gt;
&lt;P&gt;Although it may strike people as somewhat odd, I've been using Microsoft Expression Web for the last couple of years to manage the content for my MSDN blog. While the underlying platform for MSDN blogs (i.e. Community Server) certainly provides rich editing functionality, I personally prefer to have very tight control over the HTML whenever I am creating content for the Web. There are also a few things that really bother me about the editing functionality in Community Server (or at least the version of Community Server that Microsoft is currently using).&lt;/P&gt;
&lt;P&gt;Before finally choosing Expression Web, I looked at various other tools for authoring blog posts, including Windows Live Writer and even Microsoft Word 2007. However, I found that by using Expression Web and a simple "template" that I created, I could quickly and easily create blog posts with just the kind of "minimal markup" that I was looking for.&lt;/P&gt;
&lt;P&gt;My template simply contains a variety of markup that I commonly use when creating blog posts, such as:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;blockquote&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="directQuote errorMessage"&amp;gt;
&lt;/SPAN&gt;    [Direct quote, error message]&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;blockquote&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Whenever I need to create a new blog post, I simply copy my template (i.e. default.htm) into the corresponding Archive\{year}\{month}\{day} folder, rename the file to something like &lt;STRONG&gt;sharepoint-2010-sneak-peek.aspx&lt;/STRONG&gt;, and then start replacing the placeholder text with the corresponding content. Note that I have defined a few custom CSS rules in Community Server to change the style of my blog content, such as:&lt;/P&gt;
&lt;DIV class=codeBlock&gt;&lt;PRE&gt;&lt;CODE&gt;&lt;SPAN style="COLOR: #a31515"&gt;.directQuote&lt;/SPAN&gt; {
    &lt;SPAN style="COLOR: #ff0000"&gt;font-style&lt;/SPAN&gt;: &lt;SPAN style="COLOR: #0000ff"&gt;italic&lt;/SPAN&gt;;
}
&lt;SPAN style="COLOR: #a31515"&gt;.errorMessage&lt;/SPAN&gt; {
    &lt;SPAN style="COLOR: #ff0000"&gt;color&lt;/SPAN&gt;: &lt;SPAN style="COLOR: #0000ff"&gt;red&lt;/SPAN&gt;;
}&lt;/CODE&gt;&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;I define these styles in a CSS file (i.e. Themes\MSDN\MSDN.css) that is referenced by each page, thus giving me a WYSIWYG (What You See Is What You Get) experience when authoring blog content. This is one of the biggest things lacking from the editing functionality provided by Community Server, meaning that it doesn't apply your custom CSS rules when previewing a blog post before publishing.&lt;/P&gt;
&lt;P&gt;Once I have finished writing a blog post in Expression Web, I simply copy the HTML within the &lt;CODE&gt;&amp;lt;body&amp;gt;&lt;/CODE&gt; element, browse to my MSDN blog, click the &lt;STRONG&gt;Write a Blog Post &lt;/STRONG&gt;link, click the &lt;STRONG&gt;Edit HTML Source &lt;/STRONG&gt;toolbar button in the Community Server Control Panel, and then paste my content into the HTML source view.&lt;/P&gt;
&lt;P&gt;I freely admit this approach takes a little longer than simply authoring posts directly on the site, but I believe it is well worth it. Even more so, now that my blog is stored in Team Foundation Server (TFS)...&lt;/P&gt;
&lt;P&gt;Back in August while I was in Redmond for SharePoint 2010 Training, I took the opportunity of being on the Microsoft campus to rebuild my laptop with Windows 7. Prior to that rebuild, I had been running Windows Server 2008 on my laptop so that I could utilize Hyper-V regardless of whether I was working at a customer site or from home (with access to the &lt;A href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2009/09/14/the-jameson-datacenter.aspx"&gt;"Jameson Datacenter"&lt;/A&gt; and all of my various VMs).&lt;/P&gt;
&lt;P&gt;As part of this latest rebuild, I installed the latest version of the Microsoft Expression suite. One of the new features I discovered in Expression Web 3 is the ability to integrate with Team Foundation Server for source control. Note that this integration isn't completely out-of-the-box (i.e. you have to download a &lt;A href="http://code.msdn.microsoft.com/KB967483" mce_href="http://code.msdn.microsoft.com/KB967483"&gt;QFE&lt;/A&gt; to enable it).&lt;/P&gt;
&lt;P&gt;This morning, I finally found some time to move the "offline copy" of my MSDN content from my Documents folder into Team Foundation Server. I simply needed to create a new team project in TFS and then configure my workspace for source control. Once this was done, the TFS integration features of Expression Web 3 simply just worked, as shown below:&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9894525/451x375.aspx" width=451 height=375 mce_src="http://blogs.msdn.com/photos/jjameson/images/9894525/451x375.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Expression Web - my MSDN blog&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9894525/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9894525/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Notice how items that are checked into source control have a lock icon and new items that are pending have a "plus" icon next to them. In other words, the Folder List in Expression Web (which essentially shows your Web site "solution") now behaves a lot like the Solution Explorer window in Visual Studio (at least from the perspective of source control).&lt;/P&gt;
&lt;P&gt;Even though the offline content of my MSDN blog content was previously backed up on one of the servers in the Jameson Datacenter, now that it is stored in TFS, it is much easier for me to author blog posts from multiple computers (by simply doing a Get Latest from TFS). I also like the fact that my posts now have versioning -- so in the rare case where I actually go back and annotate a blog post, I can now easily "diff" my changes whenever I want.&lt;/P&gt;
&lt;P&gt;I personally love Expression Web, and now that it integrates with TFS, I love it even more! [Although I'm still getting used to the new "dark theme" introduced in v3 -- which was carried over from the previous version of Expression Blend.]&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9894524" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Web+Development/default.aspx">Web Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Linked Files in Visual Studio Solutions</title><link>http://blogs.msdn.com/jjameson/archive/2009/04/02/linked-files-in-visual-studio-solutions.aspx</link><pubDate>Thu, 02 Apr 2009 16:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9529100</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9529100.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9529100</wfw:commentRss><description>&lt;P&gt;A couple of years ago, I wrote a post introducing my system for &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx"&gt;structuring Visual Studio solutions&lt;/A&gt;. However, I apparently forgot to post a follow-up providing additional details, such as configuring assembly versioning and what I like to call "shared assembly information."&lt;/P&gt;
&lt;P&gt;Before I can cover these details, I need to first ensure that you are familiar with the concept of linking files in Visual Studio solutions, why this is a powerful feature, and when to use it.&lt;/P&gt;
&lt;P&gt;If you ever used Visual SourceSafe (VSS), you likely used its feature for sharing files across multiple projects. For example, you could check-in a file at the root of your solution, and then drag-and-drop it into other projects (i.e. "subfolders") in your solution. Thus, whenever a change was made to the file (regardless of which particular VSS project the change was made in), the next time you "got latest" the change would be reflected in all locations. This was a common way of, for example, having all of your .NET assemblies in the same Visual Studio solution specify the same assembly version.&lt;/P&gt;
&lt;P&gt;Note that Team Foundation Server (TFS) does not provide an equivalent "share file" feature. Fortunately, however, you no longer need such a feature.&lt;/P&gt;
&lt;P&gt;Back in the days of the original Visual Studio .NET and the following version, Visual Studio .NET 2003, whenever you added an existing file to a project, it copied the file into the corresponding location in the project.&lt;/P&gt;
&lt;P&gt;However, in Visual Studio 2005, the &lt;STRONG&gt;Add Existing Item&lt;/STRONG&gt; feature provided the ability to choose to either &lt;STRONG&gt;Add&lt;/STRONG&gt; the item or &lt;STRONG&gt;Add As Link &lt;/STRONG&gt;(via the little down arrow on the button in the dialog box).&lt;/P&gt;
&lt;P&gt;In other words, once you upgraded to Visual Studio 2005, it was no longer necessary to rely on any "sharing" features of your source control system in order to have multiple projects always reference the latest version of a file.&lt;/P&gt;
&lt;P&gt;Note that when you &lt;STRONG&gt;Add &lt;/STRONG&gt;an item in Visual Studio 2005 or Visual Studio 2008, the behavior is the same as earlier versions (meaning the file is copied into the corresponding location within the project). When you choose to &lt;STRONG&gt;Add As Link&lt;/STRONG&gt;, however, you simply reference the file in-place. [Don't worry, relative paths ensure that everyone on your team is free to choose whatever root folder they wish for their individual workspaces.]&lt;/P&gt;
&lt;P&gt;To illustrate this concept, I quickly built out a "demo" solution, as shown below. &lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" alt="" src="http://blogs.msdn.com/photos/jjameson/images/9529036/309x480.aspx" width=309 height=480 mce_src="http://blogs.msdn.com/photos/jjameson/images/9529036/309x480.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Linked files in a Visual Studio solution&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9529036/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9529036/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;The corresponding folder structure on disk resembles the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fabrikam 
&lt;UL&gt;
&lt;LI&gt;Demo 
&lt;UL&gt;
&lt;LI&gt;Dev &lt;EM&gt;(branch)&lt;/EM&gt; 
&lt;UL&gt;
&lt;LI&gt;Lab1 &lt;EM&gt;(branch) &lt;/EM&gt;
&lt;UL&gt;
&lt;LI&gt;AssemblyVersionInfo.cs&lt;/LI&gt;
&lt;LI&gt;CustomDictionary.xml&lt;/LI&gt;
&lt;LI&gt;Fabrikam.Demo.sln&lt;/LI&gt;
&lt;LI&gt;Fabrikam.Demo.snk&lt;/LI&gt;
&lt;LI&gt;SharedAssemblyInfo.cs&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;AdminConsole 
&lt;UL&gt;
&lt;LI&gt;AdminConsole.csproj&lt;/LI&gt;
&lt;LI&gt;Program.cs&lt;/LI&gt;
&lt;LI&gt;Properties 
&lt;UL&gt;
&lt;LI&gt;AssemblyInfo.cs&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;CoreServices 
&lt;UL&gt;
&lt;LI&gt;CoreServices.csproj&lt;/LI&gt;
&lt;LI&gt;Logging 
&lt;UL&gt;
&lt;LI&gt;Logger.cs&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Properties 
&lt;UL&gt;
&lt;LI&gt;AssemblyInfo.cs&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Note that &lt;STRONG&gt;AssemblyVersionInfo.cs&lt;/STRONG&gt;, &lt;STRONG&gt;CustomDictionary.xml&lt;/STRONG&gt;, &lt;STRONG&gt;Fabrikam.Demo.snk&lt;/STRONG&gt;, and &lt;STRONG&gt;SharedAssemblyInfo.cs &lt;/STRONG&gt;reside in the same folder as the Visual Studio solution file and are subsequently "linked into" the two Visual C# projects. Thus whenever a change is made to one of these files, the next build of each project will reflect that change.&lt;/P&gt;
&lt;P&gt;With this foundation in place, I'll explain some other recommended best practices over a series of follow-up posts, including:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/04/02/ca1704-code-analysis-warning-and-using-custom-dictionaries-in-visual-studio.aspx"&gt;Using custom dictionaries in Visual Studio&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/04/03/shared-assembly-info-in-visual-studio-projects.aspx"&gt;Shared assembly info in Visual Studio projects&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/jjameson/archive/2009/04/03/best-practices-for-net-assembly-versioning.aspx"&gt;Best practices for .NET assembly versioning&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Stay tuned!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9529100" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>DiffMerge - A Better Differencing Tool</title><link>http://blogs.msdn.com/jjameson/archive/2009/03/24/diffmerge-a-better-differencing-tool.aspx</link><pubDate>Tue, 24 Mar 2009 17:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9504266</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9504266.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9504266</wfw:commentRss><description>&lt;P&gt;Last summer, I added &lt;A href="http://www.sourcegear.com/diffmerge/" mce_href="http://www.sourcegear.com/diffmerge/"&gt;DiffMerge&lt;/A&gt; to my &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/03/22/backedup-and-notbackedup.aspx"&gt;Toolbox&lt;/A&gt; and I haven't used WinDiff since.&lt;/P&gt;
&lt;P&gt;DiffMerge can do everything WinDiff can, plus a whole lot more -- like intra-line highlighting, merging, and comparing files using configurable rulesets (although you'll likely never need any more than those that come "out-of-the-box" with DiffMerge).&lt;/P&gt;
&lt;P&gt;And since the folks at SourceGear don't mind giving away DiffMerge for free, there's no reason &lt;EM&gt;not&lt;/EM&gt; to use it!&lt;/P&gt;
&lt;P&gt;Heck, I even configure Visual Studio to use DiffMerge as my comparison tool instead of the default tool that comes with Team Foundation Server (TFS).&lt;/P&gt;
&lt;P&gt;To customize your TFS comparison tool in Visual Studio 2008:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;On the &lt;STRONG&gt;Tools&lt;/STRONG&gt; menu, click &lt;STRONG&gt;Options...&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;Options&lt;/STRONG&gt; window, expand &lt;STRONG&gt;Source Control&lt;/STRONG&gt;, select &lt;STRONG&gt;Visual Studio Team Foundation Server&lt;/STRONG&gt;, and then click &lt;STRONG&gt;Configure User Tools...&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;Configure User Tools&lt;/STRONG&gt; window, click the Add... or Modify... button as necessary to configure the following:&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;Extension: &lt;STRONG&gt;.*&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Operation: &lt;STRONG&gt;Compare&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Command: &lt;STRONG&gt;C:\NotBackedUp\Public\Toolbox\DiffMerge\DiffMerge.exe&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Arguments: &lt;STRONG&gt;%1 %2&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Obviously, you may need to adjust the path to &lt;STRONG&gt;DiffMerge.exe &lt;/STRONG&gt;as necessary for your environment.&lt;/P&gt;
&lt;P&gt;In the past, I tried other tools like BeyondCompare -- but I preferred the simplicity of WinDiff. Then, a couple of years ago, one of my peers pointed me to an internal tool called "Odd" that would do intra-line highlighting. However, I couldn't get over the fact that this was an internal tool only -- and thus not something I could recommend to customers.&lt;/P&gt;
&lt;P&gt;When I stumbled across DiffMerge, I was delighted and I haven't looked back since.&lt;/P&gt;
&lt;P&gt;Perhaps Visual Studio 2010 will ship with a vastly improved differencing tool, but in the meantime -- or just in case it doesn't -- DiffMerge is my tool of choice.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9504266" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/My+System/default.aspx">My System</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item><item><title>Branching Strategy in Team Foundation Server</title><link>http://blogs.msdn.com/jjameson/archive/2009/02/10/branching-strategy-in-team-foundation-server.aspx</link><pubDate>Tue, 10 Feb 2009 21:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9411071</guid><dc:creator>Jeremy Jameson</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jjameson/comments/9411071.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jjameson/commentrss.aspx?PostID=9411071</wfw:commentRss><description>&lt;P&gt;While attending TechReady (an internal Microsoft training conference) last week, I learned a lot -- not only about future versions of our products, but also numerous tips and tricks for current versions. One of the most valuable insights I gained was from a session on branching in Team Foundation Server (TFS). If you've read my &lt;A href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx" mce_href="http://blogs.msdn.com/jjameson/archive/2007/04/18/structure-visual-studio-solutions.aspx"&gt;previous post on structuring Visual Studio solutions&lt;/A&gt;, then you know that I'm a proponent of branching from the start in order to easily support parallel development and periodically stabilizing for a release.&lt;/P&gt;
&lt;P&gt;I had previously read the &lt;A href="http://www.codeplex.com/BranchingGuidance" mce_href="http://www.codeplex.com/BranchingGuidance"&gt;TFS Branching Guidance on CodePlex&lt;/A&gt;, although I admit it has been a rather long time. Nevertheless, I still understood the commonly used &lt;STRONG&gt;Main&lt;/STRONG&gt;, &lt;STRONG&gt;Dev&lt;/STRONG&gt;, and &lt;STRONG&gt;Release &lt;/STRONG&gt;branches. However, I discovered during the session last week that I had a fundamental misunderstanding about &lt;EM&gt;baseless merges&lt;/EM&gt; in TFS. Prior to last week, I thought a baseless merge occurred when the source and target do not share &lt;SPAN class=style1&gt;any&lt;/SPAN&gt; ancestry in the branching tree. In other words, I thought that as long as the target resides on a branch that can be traced through some lineage to the source branch, then TFS has sufficient "knowledge" (i.e. algorithms) to merge changes from the source to the target.&lt;/P&gt;
&lt;P&gt;As I stated before, this was a misunderstanding on my part. When I asked a question about trying to delay the branching for stabilization for as long as possible, the presenters of the session -- &lt;A href="http://blogs.msdn.com/jampick" mce_href="http://blogs.msdn.com/jampick"&gt;James Pickell&lt;/A&gt; and &lt;A href="http://blogs.msdn.com/mrod" mce_href="http://blogs.msdn.com/mrod"&gt;Mario Rodriguez&lt;/A&gt; -- pointed out that a baseless merge occurs whenever the target is not in a "first level" branch from the source. In other words, you can automerge from parent-to-child (or child-to-parent), but you cannot automerge from grandchild-to-grandparent.&lt;/P&gt;
&lt;P&gt;So, what does all of the mean in practical terms?&lt;/P&gt;
&lt;P&gt;It all comes down to how -- and when -- you actually branch your code.&lt;/P&gt;
&lt;P&gt;In the interest of not reinventing the wheel, allow me to pilfer one of the images from the &lt;A href="http://www.codeplex.com/TFSBranchingGuideII" mce_href="http://www.codeplex.com/TFSBranchingGuideII"&gt;updated TFS Branching Guide 2.0&lt;/A&gt;:&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" height=278 alt="" src="http://blogs.msdn.com/photos/jjameson/images/9410989/640x278.aspx" width=640 mce_src="http://blogs.msdn.com/photos/jjameson/images/9410989/640x278.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 1: Basic branch plan&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9410989/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9410989/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Note that this is a basic branch plan, but it is sufficient to demonstrate the concept. You may very well have a more complex branching strategy (e.g. a large organization like Microsoft in order to support "feature teams"). However, the essential pattern still applies.&lt;/P&gt;
&lt;P&gt;The question that I asked during the session was essentially why not postpone branching for as long as possible? In other words, why not branch &lt;STRONG&gt;Release&lt;/STRONG&gt; first, and then branch for hotfixes and service packs as necessary? In my mind, this alternative approach reduces the merge effort by only branching at the point in time when we actually need a branch (e.g. to stabilize for a release). At some later point in time after the release when we actually need a hotfix or service pack branch, then we'll create it from the &lt;STRONG&gt;Release&lt;/STRONG&gt; branch. In response to my question, Mario termed this "reactive branching" -- which seems like a very good way to describe it. To help visualize the difference, I mocked up the following figure.&lt;/P&gt;
&lt;DIV class=image&gt;&lt;IMG title="" height=278 alt="" src="http://blogs.msdn.com/photos/jjameson/images/9410992/640x278.aspx" width=640 mce_src="http://blogs.msdn.com/photos/jjameson/images/9410992/640x278.aspx"&gt; 
&lt;DIV class=caption&gt;Figure 2: "Reactive" branch plan&lt;/DIV&gt;
&lt;DIV class=imageLink&gt;&lt;A href="http://blogs.msdn.com/photos/jjameson/images/9410992/original.aspx" target=_blank mce_href="http://blogs.msdn.com/photos/jjameson/images/9410992/original.aspx"&gt;See full-sized image.&lt;/A&gt; &lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;There are a couple of significant problems with reactive branching:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;In order to merge code changes from a QFE (a.k.a. hotfix) or service pack back into &lt;STRONG&gt;Main&lt;/STRONG&gt; (and remember, we almost always want the fixes in QFEs to be incorporated into &lt;STRONG&gt;Main&lt;/STRONG&gt;), we would either need to first automerge the changes into the &lt;STRONG&gt;Release &lt;/STRONG&gt;branch and then merge the changes into &lt;STRONG&gt;Main &lt;/STRONG&gt;-- or else perform a baseless merge (which, generally speaking, we want to avoid). If we merge the changes into the &lt;STRONG&gt;Release &lt;/STRONG&gt;branch, then that code no longer reflects the actual Release build (e.g. v1.0) but rather the Release build plus some number of changes. Yes, we could still use labels to "snapshot" the source code for the Release version, but as James pointed out, labels can be manipulated and therefore may not be sufficiently "bulletproof" to meet your requirements.&lt;/LI&gt;
&lt;LI&gt;We could still use reactive branching, but avoid merging through &lt;STRONG&gt;Release&lt;/STRONG&gt; by renaming a branch (e.g. the &lt;STRONG&gt;Release&lt;/STRONG&gt; branch is renamed to &lt;STRONG&gt;Service Pack&lt;/STRONG&gt;, and a new &lt;STRONG&gt;Release&lt;/STRONG&gt; branch is created and "locked down" from a permissions perspective). However, this requires significantly more work with each release -- work that can be avoided altogether by using the branching strategy shown in Figure 1.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So, in summary, while it may seem a little backwards to create your &lt;STRONG&gt;Service Pack &lt;/STRONG&gt;branch before your &lt;STRONG&gt;Release &lt;/STRONG&gt;branch, there are compelling reasons to do so. As for me, I now consider my "reactive branching" strategy to be a thing of the past.&lt;/P&gt;
&lt;P&gt;Thanks to James and Mario for setting me straight!&lt;/P&gt;
&lt;P&gt;By the way, if you haven't read the branching guidance created by the VSTS Rangers, I highly recommend it. Very good stuff.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9411071" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jjameson/archive/tags/Core+Development/default.aspx">Core Development</category><category domain="http://blogs.msdn.com/jjameson/archive/tags/TFS/default.aspx">TFS</category></item></channel></rss>