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.

8 comments
Comments feed for this article
August 22, 2007 at 9:02 pm
Aymeric
Nice! I know a few who will be happy
If I had already installed the open source tasks package (http://msbuildtasks.tigris.org/), could I use the FileUpdate task (“Replace text in file(s) using a Regular Expression.”) instead of the powershell task?
August 22, 2007 at 9:10 pm
Mitch Denny
Hi Aymeric,
Yeah – but if you used the FileUpdate task you wouldn’t have been able to use PowerShell in the solution. PowerShell is my second love
Actually, as it happens I think we already have those tasks up on the build server.
August 22, 2007 at 9:44 pm
Three out of five ain’t bad… « notgartner
[...] Tomorrow I should be able to knock over the remaining two tomorrow with Chris’ help. As a side note, I blogged about how I tackled number five over on the TFS Now blog. [...]
August 22, 2007 at 11:37 pm
Daniel Bartholomew
Love your work.
January 18, 2008 at 10:05 am
Matthew Yost
I have a problem with the script. It appears that it’s not running the Powershell script to give me the fixed file. Does the XML need to be placed somewhere specific?
February 28, 2008 at 6:33 am
Nate A
I also don’t see the “fixed” version either. If my build results only show there error stating that the “fixed” sln file is not found, is there another area I can check to see if there is an error with the creation of the “fixed” sln file?
Thanks.
October 29, 2008 at 10:12 pm
pvila
I’m getting this error in the BuildLog.txt file:
e:\CompilationDir\…\…\project1.csproj(143,11): error MSB4019: The imported project “e:\Microsoft.CSharp.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
(I have replaced V9.0 by V8.0 and the powershell is working right).
Any clue?
December 5, 2008 at 7:46 pm
Praful Udade
Hi,
I have similar issue. My application is window based application in VS2008 with framework 2.0. If I used MSBuild to automate build process. It shows me following error.
Solution file error MSB5014: File format version is not recognized. MSBuild can only read solution files between versions 7.0 and 9.0, inclusive.
It works fine, if I changed framework to 3.5. I tried above option in MSBuild file, but it doesn’t work in my case. Am I missing any steps or any other ways is required?
Thanks
Praful