Building Web Application Projects with CCNET

One of the things about Visual Studio 2005 I disapprove of the most is the way features related to your project are stuffed into the local devmachine environment under Program Files. Among other things the coming GAT (guidance automation toolkits) work this way, and so does the new bootstrapper packages. There are many drawbacks to this strategy, and they all become apparent when you decide to do distributed development against a common build environment.

So, when you're starting up with your Web Application Project (WAP) and install the MSI plugin for Visual Studio 2005 you pretty much know that this will break on the buildserver, or your fellow developers machine if the same MSI is not installed on that client. Most likely the other client (CCNET or another dev) will get a taste of this error:

error MSB4019: The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

Of course you could select the dictator strategy and enforce distributed installation of the WAP MSI installer, but I tend to prefer to keep my project completely packaged.

First copy the targets file to your solution directory and add it as a solution item so it is included in sourcecontrol. Then unload your WAP by right clicking in the Solution Explorer and then select "Edit MyWAP.csproj" to edit the MSBuild markup. Change this line:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />

To this:

<Import Project="$(SolutionDir)\Microsoft.WebApplication.targets" />


Now save your csproj file and reload the project by right-clicking the unloaded project node in the solution explorer. This will give you a security warning (beware! you've edited your own build file) that you can safely ignore.

Now, Visual Studio automatically feeds MSBuild with the SolutionDir property so this will load in your IDE, but if you're going to call MSBuild from another tool, like NAnt, make sure you pass in a value for SolutionDir when executing msbuild.exe.

I know the WAP thing is reused across multiple projects and it is a good thing to have the templates in the "Microsoft Visual Studio 8" folder for easy access, but it does create a lot of work for us that want to keep our projects buildable in multimachine environments.

Comments

# svdoever said:

I totally agree with you. In our software production line for SharePoint 2003 we include all tools like NAnt, custom NAnt tasks, zip, cabarc etc. etc. with the code into the repository, so they are automatically available on the build server and all development machines when code is checked out from Subversion. We even include NAnt in the automatically build deployment packages so we can utilize it in the deployment process.

Serge van den Oever [Macaw]

Monday, June 19, 2006 6:43 PM
# Yani Dzhurov said:

Hi,

very nice and useful tip!

Saved me a lot of head-banging:)

Thanks,

Yani

Friday, May 18, 2007 10:10 AM
# Ninja said:

Finally, some real information. I regularly curse and yell when trying to do a multi-server deployment and I hit something like this. Not to mention the fact the build engineer gets blamed for all things broken when something like this happens. :) Thanks!

Monday, August 13, 2007 1:27 PM
# Murray said:

Sweet, and thanks for putting that error message in your article, makes Google work like magic :-)

Tuesday, September 4, 2007 10:34 PM
# Mike said:

First of all, thanks for sharing this information. This was very frustrating for me as I am fairly new to MSBuild.

I am using a combination of NAnt and MSBuild for my overnight builds. I use NAnt because of all of its nice features (like emailing on failed builds). I use MSBuild (via NANTCONTRIB) to actually build the source because it is convenient (and I want to shelter myself from Microsoft changes to the build files). I am wondering, how do I set $(SolutionDir)? I tried setting an environment variable, but now I get the following error message:

<pre>

The value "*Undefined*\Microsoft.WebApplication.targets" of the "Project" attribute in element <Import> is invalid. Illegal characters in path.</pre>

It looks to me like MSBuild did not pick up the value of $(SolutionDir).

Thanks for any help that you can provide.

Monday, November 5, 2007 3:53 PM
# hartertobak said:

Thanks for sharing - just what I was looking for

Wednesday, June 11, 2008 7:12 AM
# msimner said:

Good insight here - I have a vanilla build machine without Visual Studio, and didn't like the idea of having to manually alter every web project file, so chose the (less righteous) path of least resistance and copied the offending folder c:\program files\msbuild from a dev machine and hey presto...

Tuesday, August 5, 2008 12:19 AM