Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing multiple values to Wix DefineConstants property with MSBuild

I'm currently integrating my Wix projects in MSBuild. It is necessary for me to pass multiple values to the Wix project. One value will work (ProductVersion in the sample below).

<Target Name="BuildWixSetups">
    <MSBuild Condition="'%(WixSetups.Identity)'!=''"
                Projects="%(WixSetups.Identity)"
                Targets="Rebuild" Properties="Configuration=Release;OutputPath=$(OutDir);DefineConstants=ProductVersion=%(WixSetups.ISVersion)" ContinueOnError="true"/>
</Target>

However, how do I pass multiple values to the DefineConstants key? I've tried all the 'logical' separators (space, comma, semi-colon, pipe-symbol), but this doesn't work.

Has someone else come across this problem?

Solutions that don't work:

  1. Trying to add a DefineConstants element does not work because DefineConstants needs to be expressed within the Properties attribute.
like image 887
Sardaukar Avatar asked Feb 03 '09 10:02

Sardaukar


2 Answers

The problem:

The MSBuild task (not MSBuild.exe, the MSBuild task named MSBuild) cannot handle multiple constants used by WIX projects. Normally you would specify the properties in your build script like:

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1;SOMETHINGELSE=2&quot;" />

What you see however, when looking at the build logs is the MSBuild separates the constants and does not keep the values grouped together like you would expect - similar to:

Task "MSBuild" Global Properties:
Configuration=MyConfig
Platform=x86
DefineConstants="SOMETHING=1
SOMETHINGELSE=2"

So when candle tries to use those constants it typically responds with "error CNDL0150: Undefined preprocessor variable '$(var.SOMETHINGELSE)'. What this means is the MSBuild task is not properly handling properties which contain multiple '=' in the value even when grouped within quotation marks. Without the property value being grouped in quotation marks, they should obviously be treated as separate properties, rather than a single value.

The workaround:

In order to fix this problem, you need to call MSBuild.exe directly and pass those values to it manually.

msbuild.exe /p:Configuration=MyConfig /p:Platform=x86 /p:DefineConstants="SOMETHING=1;SOMETHINGELSE=2" YourSolution.sln

This will get your constants the work the way you want them to, without having to redesign your WiX installation project.

NOTE: If you're only using a single constant you can still use the MSBuild task like so:

<MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1&quot;" />
like image 183
Jeff Winn Avatar answered Nov 12 '22 02:11

Jeff Winn


The problem lies in passing the name-value pairs to the MSBuild task, and then having MSBuild parse them properly so they can be passed to the Candle task. It seems that MSBuild can handle a list of simple names, or a single name-value pair, but not a list of pairs.

My solution is to escape the list when it's passed into the MSBuild task, and unescape it again when it goes to the Candle task.

In your MSBuild file, define the pairs in a property like this:

<PropertyGroup>
    <WixValues>
        One=1;
        Two=2;
        Three=3;
    </WixValues>
</PropertyGroup>

When you call the MSBuild task, escape the property (requires MSBuild 4):

<MSBuild 
    Projects="setup.wixproj"
    Properties="WixValues=$([MSBuild]::Escape($(WixValues)))" />

The unescaping has to be done in the wixproj file, but there's no need to edit the file by hand. Just open the project's properties, go to the Build tab, and where it says "Define preprocessor variables", put:

$([MSBuild]::Unescape($(WixValues)))

This works even if there are other variables already in that box; just add this to the list along with a semicolon.

You'll see in the MSBuild log that the candle.exe tool receives the arguments correctly:

candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release...
like image 36
Rory MacLeod Avatar answered Nov 12 '22 02:11

Rory MacLeod