In this post, I show how I’ve managed to integrate WiX into my NAnt build scripts while retaining consistency of versioning.

In most build scenarios, the build script is in charge of versioning. For example, the following NAnt target updates the master build number for a system, leaving the result in the property build.version.

<target name="compile.version"
        description="Update build version">
 
   <version startdate="1 Jan 2006" 
             path="version.txt" 
   prefix="build"/>
 
</target>

Once this target has executed, the next step is to inject the version number into our assemblies and our installers. For .NET assemblies, NAnt has a very useful <asminfo> task which can be used generate source files for C# and Visual Basic that contain the version number.

To achieve the same results for our WiX files, the <echo> task comes to the fore.

<target name="compile.installer">
 
  <!-- Generate a version.wxs file -->
 
  <echo file="${wix.src.dir}\version.wxs" 
        message="&lt;Include&gt;"/>
 
  <echo file="${wix.src.dir}\version.wxs" append="true"
        message="&lt;?define version=&quot;${build.version}&quot; ?&gt;"/>
 
  <echo file="${wix.src.dir}\version.wxs" append="true"
        message="&lt;/Include&gt;"/>
 
  ...
 
</target>

The first <echo> statement overwrites any existing version.wxs file, and the following two <echo> statements append additional lines. If you decipher all the XML encoding, you’ll see that the output file will look something like this:

<Include>
    <?define version="1.2.3.4" ?>
</Include>

With this version file in place, the version can be pulled into the main WXS file with an include directive.

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wix">
 
   <?include version.wxs ?>
 
   ...
 
</Wix>

The last step is to refer to the version number where required, replacing the hard coded values. As a minimum, replace the Version attribute on the Product element.

<?xml version="1.0" encoding="utf-8"?>
<Product Id="????????-????-????-????-????????????" 
         Name="My Example Product" 
         Language="1033" 
         Version="$(var.version)" 
         Manufacturer="Niche Software" 
         UpgradeCode="$(var.UpgradeCode)">
 
  ...
 
</Product>

The version number can also injected into the filename of the final MSI, as can be seen in this build fragment.

<target name="compile.installer">
 
  ...
 
    <exec program="lib\wix\candle.exe" verbose="true">
        <arg value="-out"/>
        <arg file="${wix.tmp.dir}\rbquery.wixobj"/>
        <arg file="${wix.src.dir}\rbquery.wxs"/>
    </exec>
 
    <exec program="lib\wix\light.exe" verbose="true">
        <arg value="-out"/>
        <arg file="${wix.build.dir}\rbquery-${build.version}.msi"/>
        <arg file="${wix.tmp.dir}\rbquery.wixobj"/>
    </exec>
 
</target>

One catch to be aware of is that changing the name of the MSI file requires that each newer version of the installer be a major upgrade. If you want to perform minor updates or patches with your MSIs, the name of the MSI must remain unchanged.

Comments

blog comments powered by Disqus

Download

Wix Techniques

Next Post
Reflector  28 Aug 2008
Prior Post
Visual Studio Shortcuts for StyleCop  26 Aug 2008
Related Posts
Browsers and WSL  31 Mar 2024
Factory methods and functions  05 Mar 2023
Using Constructors  27 Feb 2023
An Inconvenient API  18 Feb 2023
Method Archetypes  11 Sep 2022
A bash puzzle, solved  02 Jul 2022
A bash puzzle  25 Jun 2022
Improve your troubleshooting by aggregating errors  11 Jun 2022
Improve your troubleshooting by wrapping errors  28 May 2022
Keep your promises  14 May 2022
Archives
August 2008
2008