MSBuild - The Basics

When I first started using Visual Studio .NET NAnt quickly became the de facto build tool. NAnt was billed as "kind of like make without make's wrinkles. In practice it's a lot like Ant". Build and automation was one of holes in the .NET build system being filled by the generous work of open source development. NAnt worked well, but as is the case with frameworks that fill small gaps, Microsoft has filled in the space by developing the capabilities of MSBuild.

MSBuild constitutes the underlying technology used to build and compile your projects, in truth if you have done any software development using Visual Studio recently then you have inevitably used MSBuild. MSBuild actually follows the pattern of an interpreted programming language (like Perl or Python) but relies on XML When you hit F5 in Visual Studio you are actually doing is starting process invoked by MSBuild (MSBuild.exe). While compiling is the most common use case for MSBuild it also well known as an opportunity to automate tangential build tasks, like running tests; minifying files or copying the output to a new location. All this functionality is explicitly available to TFS (which is why we are upgrading at work) but MSBuild can be used independently, so you can run all kinds of tasks using MSBuild a command prompt.

A Quick History

When MSBuild was introduced with Visual Studio 2005 (.NET 2) it was useless, in fact the only thing it could really do was compile your work. With the release of Visual Studio 2008 MSBuild was improved and its functionality more closely resembled what we would expect from a modern build framework. However it was not until the release of MSBuild 4 (Visual Studio 2010) that we got a refreshed object model and many of the language enhancements that make working with MSBuild a much more intuitive, first class automation framework experience.

Anatomy of a Build File

Project - Is the highest level container for all build level instructions, note in the below example the namespace associated which pulls in the XSD reference for the build containers, targets and tasks.

Target - This is the highest level organization (or container) for a piece of build logic we want to add at least one Target is necessary for MSBuild to be able to run without error.

Task - Tasks provide the code that runs during the build process, it provides us with the opportunity to perform atomic build operations. While we have an exhaustive list of tasks to use out the box, you can actually author your own using implements the ITask interface.

Properties - Allow us to consider more interesting build scenarios because it allows us to save temporary data in memory, Properties are scalar variables based on key value pairing. See the PropertyGroup below. Also note that there are a list of reserved properties that give you access to environment details (run with command with /v:diag).

Items - Items are similar to properties in that they store data but an item allows to pull together a list of related files in, for example, a folder with a particular extension..

Here is an example of a basic MSBuild file with Targets, Tasks and Items that show a list files based on defined folder:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="">
    <csharp Include="$(BuildPath)" />
  <Target Name="MainBuild">
    <Message Text="Start building in this location $(BuildPath)" />
    <Message Text="File list: @(csharp)" />

You can call the defined Target explicitly using this command line:

msbuild somebuild msbuild /target:MainBuild

Or implicitly using this one:

msbuild somebuild msbuild

You can override the BuildPath property like this:

msbuild somebuild msbuild /target:MainBuild /p:BuildPath=C:\temp

There are quite a few build/automation frameworks to choose from Gulp and Grunt come to mind, our selection was made based on the natural relationship between TFS and MSBuild, the choice for you ultimately comes down to what other tools you may need to integrate with and what your most comfortable using.

Comment Section

Comments are closed.