MSBuild in Visual Studio Part 3: How the IDE Writes Properties

In our last post we looked at how the project system uses MSBuild to read properties out of the project file. Now that we know how properties get into the project system, let’s take a look at how updated properties get pushed back to the project file.

As you might expect after reading the previous posts, the project system uses an MSBuild API to do the dirty work. The API in this case is Project.SetProperty(). The call looks something like this:

Project.SetProperty(“Optimize”, “true”, “'$(Configuration)|$(Platform)' == 'Retail|AnyCPU'”);

MSBuild searches through the project file for a PropertyGroup with a condition that matches the passed in string then updates the property appropriately. This is very convenient for the project system as it now no longer has to worry about overwriting any customizations someone might have added to the project file. MSBuild just goes and uses the .NET XML classes to poke at the XML elements directly.

This works well, but as Rajeev pointed out during his talk there are ways this can get funky. The first way is if someone has customized the project file as follows:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

    <!-- Other standard goo from the project file has been
removed for clarity. -->

    <Optimize>true</Optimize>

  </PropertyGroup>

  <!-- This property group was added by someone who customized
the project file. -->

  <PropertyGroup>

    <Optimize>false</Optimize>

  </PropertyGroup>

In this case MSBuild will diligently go and update the Optimize property inside the property group with the condition tag. After all, that’s what the project system asked to have updated. The only problem is it will essentially have no effect due to the second property group that someone (maybe you?) added. It will always override anything in a property group above it, and when the user goes to look in the UI they’ll see the optimize property is still false, even though they tried to set it to true. This is, in fact, the correct behaviour but it is rather strange.

The second way this can get funky is when you start to think about escaping the property values. That’s so funky it’s worthy of at least three posts. Hold on to your heads, grab your favourite beverage, and stay tuned to go on a wild ride…

[ Author: Neil Enns ]