Update: We have now found a better way of doing this.
Last night whilst on the way to the airport Darren Neimke (our DevCentre manager and first customer of TFS Now) gave me a call to talk about an issue he was having with TFS Now (actually Team Foundation Server 2005 generally) and Visual Studio 2008. The good thing about using your own stuff is that you stumble across problems (hopefully) before your customers do which gives you a head-start getting them fixed or at least working around them.
One of the problems that Darren was having was getting a .NET 2.0 solution authored with Visual Studio 2008 to build successfully under Team Build 2005. Here is a screen shot of the build failure.
Even though the code being compiled targets the .NET 2.0 runtime the solution file itself has changed its format version and so MSBuild (from .NET 2.0) throws an error trying to process the file. To illustrate the (minor) difference between the Visual Studio 2005 and Visual Studio 2008 solution file formats, here are two screen shots.
First a Visual Studio 2005 solution file header:

Second a Visual Studio 2008 solution file header:
Notice that the Format Version value has been changed from “9.0″ to “10.0″. I’m sure that there are some interesting stories about why these numbers are nine and ten respectively since Visual Studio 2005 is actually Visual Studio 8.0, and Visual Studio 2008 is actually Visual Studio 9.0 – but anyway, I digress.
In a nutshell, the problem is that the version of MSBuild that Team Build 2005 integrates with gets to a solution file with Format Version 10.0 and simply falls over with the following error:
Build FAILED.
C:\Builds\TFSNow\TfsNow-PublicWebsite-Continuous\Sources\PublicWebsite.sln(2): Solution file error MSB5014: File format version is not recognized. MSBuild can only read solution files between versions 7.0 and 9.0, inclusive.
The reason we get any sort of output at all from Team Build is due to the fact that the first build file that it actually processes is the TFSBuild.proj file located at $/[TeamProject]/TeamBuildTypes/[BuildType]/TFSBuild.proj.
In order to work around this problem we need to get creative. Because TFSBuild.proj actually starts getting processed we actually have an opportunity to inject some pre-processing logic to “fix” up the PublicWebsite.sln file. At the command prompt I tested the following PowerShell pipeline that transformed the solution file:
get-content PublicWebsite.sln | % { $_.Replace(“Format Version 10.0″, “Format Version 9.0″) } | set-content PublicWebsite.Fixed.sln
This one is pretty simple. It pipes each line from the solution file through a little replacement routine and spits it back out into a new file. If I tell MSBuild to build this file it won’t blow up straight away but it will still fail. The problem is that the <Import /> elements in all of the *.csproj MSBuild files are looking for an updated set of *.targets files for Visual Studio 2008.
Rather than install Visual Studio 2008 on our build server I thought it might be easier to just copy the directory:
C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0
To:
C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0
This is a fairly major hack but when I triggered MSBuild on the “fixed” solution file it seemed to pay off (only a few warnings about quality tool references). The next step is to get this all working under Team Build so that the solution file is dynamically fixed and Darren can continue developing with Visual Studio 2008.
Since I used PowerShell, I needed a MSBuild task that would allow me to invoke a piece of PowerShell code from within an MSBuild script. I found this great implementation of just such a task on Arild Fines’ blog. Because Arild developed his task before PowerShell shipped, when you download the zip file with the binary, you will need to recompile the code, this worked first time for me – no modifications required.
Once that is done upload the PowershellMSBuildTask.dll file into the same location in version control as TFSBuild.proj build file and modify said file by adding the following XML:
You will also need to update the SolutionToBuild item group to point at the “fixed” solution file. Once all this in place you should be able to build Visual Studio 2008 solution files targeting the .NET 2.0 Framework via Team Build. I’m still looking at ways that Team Foundation Server 2005 users can stagger their adoption of Visual Studio 2008 by building .NET 3.5 projects on Team Build 2005, if I come up with a workable solution I will post it here. As proof that all this works, here is a screen shot of the successful build.
Finally, I have a few thoughts about the whole Visual Studio 2008/Team Foundation Server 2008 migration pain that people are about to go through. First of all it would have been nice if Microsoft could have shipped an updated Team Build 2005 build server (Team Build 2005 R2 anybody?) which could handle kicking off builds with a version of MSBuild that can support .NET 3.5 projects.
Visual Studio 2008 adoption is probably going to lead Team Foundation Server 2008 adoption in most organizations as I can’t see many companies opting to upgrade a working Team Foundation Server 2005 installation to Team Foundation Server 2008 even with a Go Live license in place. Without a half-way point a lot of organizations might hold off starting Visual Studio 2008-based projects until Team Foundation Server 2008 actually ships and they can move all of their code forward.