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 b
A workaround hack.
Assumptions:
In MSBuild:
<DefineConstants>Debug;use_$(SomeEnumValue)</DefineConstants>
In WiX:
<?ifdef $(var.use_EnumValue1) ?>
...
<?elseif $(var.use_EnumValue2) ?>
...
<?endif?>
You could pass it as parameter, not constant. The code will look like this:
<MSBuild ...
Properties="ProductVersion=%(WixSetups.ISVersion)" />
Now in WiX project add a constant:
<DefineConstants>BuildVersion=$(ProductVersion)</DefineConstants>
And use it in *.wxs file where needed:
$(var.BuildVersion)
For instance:
<Product Id="*" Name="My Company" Language="1033" Version="$(var.BuildVersion)"... />
This will work with multiple parameters.
The following lines worked when I included them in a .wixproj file (using Visual Studio 2010).
<PropertyGroup>
<DefineConstants>Const1=Value1;Const2=Value2;Const3=Value3</DefineConstants>
</PropertyGroup>
I still had a lot of trouble getting this to work, but peices of each answer above, contributed to my solution, so I wanted to share.
Environment: TFS Build Server 2010 - Powershell calling MSBuild.exe Wix 3.6 is installed on the build server
Goal is to pass the build version number and 5 directories into MSBuild, so that Candle.exe will receive them correctly
The Build calls a command file at the end of the build, and that command file, includes a step to call a powershell script to build the Wix installer. It passes in the version number for the build and the source and output directories (the output is a UNC fileshare reference \tfsbuildserver..)
To get it to work, in the Powershell ps1 file,
there should be no additional quotes around any file names with spaces
$msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
$options = " /p:Configuration=Release /p:Platform=x64 "
$options = $options + " /p:DefineConstants="""
$options = $options + "SolutionDir=" + $SourceDir
$options = $options + "%3bTFSBuildSourceLanding=" + $OutputLocation + "SharepointWebRoot\Landing"
$options = $options + "%3bTFSBuildSourceLandingAdmin=" + $OutputLocation + "SharepointWebRoot\LandingAdmin"
$options = $options + "%3bTFSBuildSourceRegistration=" + $OutputLocation + "Extranet_Registration"
$options = $options + "%3bTFSBuildSourceGAC=" + $OutputLocation + "GAC"
$options = $options + "%3bTFSBuildSourceSQL=" + $OutputLocation + "SQL"
$options = $options + "%3bProductVersion=" + $BuildVersion + """"
$build = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Build"
$clean = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Clean"
Write-Host "Building Wix Installer..."
Invoke-Expression $clean
Invoke-Expression $build
Inside the wixproj file, we have to unescape (down at the bottom, where it says to uncomment to modify)
<Target Name="BeforeBuild">
<CreateProperty Value="$([MSBuild]::Unescape($(DefineConstants)))">
<Output TaskParameter="Value" PropertyName="DefineConstants" />
</CreateProperty>
</Target>
Also note that in Visual Studio, I will use the debug settings, and I can have defaults set for these values, in the Build Tab, "Define preprocessor Variables"
in the Release settings this item should be blank as it will get passed in on the command line above.
This worked for me and allowed me to pass in items with yet to be defined key value pairs. Not the most elegant but I'm not a coder.
msbuild test.proj /p:PassedInProp="ProductVersion=45;rt=669;wewanttoknow=test5"
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<test Include="$([MSBuild]::Unescape($(PassedInProp)))" />
</ItemGroup>
<Target Name ="Test">
<CreateItem Include ="$([System.String]::New('%(test.identity)').Split('=')[0])" AdditionalMetadata="value=$([System.String]::New('%(test.identity)').Split('=')[1])">
<Output TaskParameter="Include" ItemName ="Test2"/>
</CreateItem>
<Message Text ="Key: %(test2.identity) Value: %(test2.value)"/>
</Target>
</Project>
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...