Friday, May 6, 2011

Hidden features of msbuild

I have an interest in msbuild this week. I'm cleaning up a lot of extremely complex build scripts. Digging in surprises me with how much it can do - msbuild is sort of a hidden feature of .NET programming in itself.

In the SO convention that questions must have answers, in a few days or a week, I'll mark the most useful or coolest hidden feature(s) as accepted.

   let bestAnswer suprise slick useful = (surprise + slick + 2*useful)

Definition of useful: I'm updating existing msbuild scripts that: package (zip files) websites and utilities, CC.NET integration, launch tests (UT + selenium), build databases. I'm adding (new targets, even more useful): deploy to VMWare virtual servers, chained builds (fast build immediately, queue slow tests). If you refer to an external library (like MSBuild community tasks), it would be nice to know how to get it.

Some msbuild surprises I've already found.

  • Hello world using the Message task and Properties.
  • Using msbuild as an installer for an extremely complex server product. MSB community tasks managed IIS server setup. The WriteLinesToFile and XmlUpdate tasks wrote server specific configuration files. If you've work with MSI, you'll know that anything is better than MSI for installation.
  • For newbies: CSProj and Vbproj files are the same as msbuild "proj" files. To edit directly: Unload your csproj or vbproj, then right click project and select edit. This is nicer and more powerful than working with clunky pre-build / post-build events.
  • MSBuild comes with the generic .NET installation. Unlike other fancy tools, you can use it on a totally clean server / desktop.

Here is msbuild Hello World After I wrote it, I found the MSDN hello world.

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build;Test" xmlns="">
  <Target Name="Hello">
    <Message Text="Hello, $(Who)" Importance="high" ></Message>
  <Target Name="Build" DependsOnTargets="Hello"/>
  <Target Name="Test"/>
From stackoverflow
  • MSBuild has a number of nice features. I like

    recursive file specs

    <Files Include="$(src)\**\*.cs" Exclude="$(src)\**\*test.cs" />

    Batching and Item Metadata

     <F Include="SampleApplication.t">
     <F Include="SampleApplication2.t">
    <F Include="SampleApplication3.t">
    <Target Name="Build">
    <Touch Files="%(F.FullPath)" AlwaysCreate="True" 
            Condition=" '%(F.Version)' > '1' ">
    <Output TaskParameter="TouchedFiles" ItemName="CreatedFiles"/>
    <Message Text="Created files = @(CreatedFiles)"/>
    <Message Text="%(F.Identity) %(F.Version)"/>

    Target level dependency analysis

    <Target Name="Build"
               Outputs="@(MyItems -> '$(MyItems)\%(filename).dll'">
    Marc Gravell : The recursive ** is a trick I use for sharing code between frameworks (CF/Silverlight/.NET/etc) - very useful.
  • You can reference one msbuild file from within another. All of our targets, such as those for running NCover, SourceMonitor, Duplo, etc. are within a common targets file. For each project, we create an msbuild file with a PropertyGroup and ItemGroup section, followed by an include to the common targets. This guarantees that all of our builds will run the same set of analysis tasks and save us time writing the scripts.

    • I have found the MSBuild Extension pack to be incredibly useful. The documentation is very well organized and easy to find the info you need.

    • They have a section in configuring intellisense for build files, that can be found here

    • Attrice has an incredible tool that I use often if I need to work on build scripts. What makes it worth your while to try it out, is that it has a debugger that will show you the dependent tasks, as it executes your build script, with auto's and watch variables while it is running the build script. Microsoft Build Sidekick v2.3

    • Setting SVN to quiet, this feels to me to have increased the speed of the build process a lot. Adding the following to your MSBuild.Community.Tasks.Subversion.SvnExport will run the build without logging each and every file that it gets out of SVN

      Arguments="--force -q"

  • Use the /M command-line parameter to enable usage of all available CPU cores.

  • Hi, This is not really a hidden feature but I think that batching is very powerful when understood.

    For more information you can read my related blog entries at:


Post a Comment