It almost seems like it would be an easy thing to have wix (an xml file-based installer build system) see and use variables passed to it by a controlling msbuild script (an xml file-based build system). The reality is a bit more difficult.
We started off wanting to have Wix build a package for us based on files in a version-dependent folder. As we change the version number, Wix should look in a different folder for the files. We also wanted this to work on a local (dev) machine and on a build machine running a TFS build agent.
So for a “BuildNumber” maybe an environment variable:
or a plain old wix variable:
Now, we can define a variable in the .wxs source or .wxi include file but none of those are settable from “the outside world” of msbuild or the command line. We have to rely on a built-in wix feature called DefineConstants which is a semi-colon delimited list of key value pairs. Opening the .wixproj in Visual Studio, the project property look like this:
Variables get passed to the wix commandline toolchain using the
So, if you don’t have a variable defined, msbuild defaults to an emtpy string, which is maybe not what we want. We can address that by unloading the project and hand editing to introduce a default. The MsBuild idiom for this is to define a property but add a condition to only set it if it doesn’t already have a value.
DefineConstants looks like this in the project file:
<PropertyGroup> <DefineConstants>Debug;NAME=Rob;JOB=Dev;BUILDNUMBER=$(BUILDNUMBER)</DefineConstants> </PropertyGroup>
We need to define a property upstream of this:
<PropertyGroup> <BuildNumber Condition=" '$(BuildNumber)' == '' ">188.8.131.52</DefineConstants> </PropertyGroup>
In the calling MsBuild script we can use the
AdditionalProperties meta data
for a project to pass the variable to wix.
<ItemGroup> <ProjectList Include="SetupProject1.sln"> <AdditionalProperties>BUILDNUMBER=$(MyBuildNumberFromAssembly)</AdditionalProperties> </ProjectList> </ItemGroup> <Message Text="Build is: $(MyBuildNumberFromAssembly)"/> <MSBuild Projects="@(ProjectList)"/>
Then we can pull the build number in by reading a text file or reflecting on an assembly version or by reading it from the command line.