147

I wrote an application and its WiX installer and put it under version control using subversion. When the WiX installer builds I want its version number to be the current build version of the application. How do I accomplish this? I used c# to code the application.

N.B. I am using ccnet to build this project

AndyUK
  • 3,933
  • 7
  • 42
  • 44
Draco
  • 16,156
  • 23
  • 77
  • 92

6 Answers6

196

You could use Product/@Version="!(bind.FileVersion.FileId)" (replace FileId with the Id of the file from which you'd like to get the version number) and light.exe will populate the value with the version of the file referenced by the FileId. See the WiX v3 documentation for all the available variables.

Rob Mensching
  • 33,834
  • 5
  • 90
  • 130
41

In case someone is looking for an actual XML example, this works with .NET assemblies (and you don't have to do the Assembly or KeyPath attributes). I eliminated unrelated code with [...] place holders:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product [...] Version="!(bind.fileVersion.MyDLL)">
        [...]
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Id="INSTALLDIR" Name="MyDLLInstallLocation">
                    <Component Id="MainLib" Guid="[...]">
                        <File Id="MyDLL" Name="MyDll.dll" Source="MyDll.dll" />
                        [...]
                    </Component>
                    [...]
                </Directory>
            </Directory>
        </Directory>
    </Product>
</Wix>
K0D4
  • 2,373
  • 1
  • 27
  • 26
  • where is it fetching the actual version number? – foobar Oct 10 '17 at 08:01
  • 1
    @foobar Its been a while since I was in here, but if you look at the string `!(bind.fileVersion.MyDLL)` it uses the 3rd part in reference to the ` – K0D4 Oct 10 '17 at 19:46
  • This worked well for me. Works for compiled executables as well as dll's which is great for pinning the installer version and UI content to the exe assembly info, without having to change things in multiple places – rcbevans Jan 10 '19 at 20:56
39

I did this in one of my projects by writing a preprocessor extension to read the file version from my executable. So the WiX file looks something like:

<?define ProductName="$(fileVersion.ProductName($(var.MyApp.TargetPath)))" ?>
<?define CompanyName="$(fileVersion.CompanyName($(var.MyApp.TargetPath)))" ?>
<?define ProductVersion="$(fileVersion.ProductVersion($(var.MyApp.TargetPath)))" ?>
<Product 
    Id="<product ID>" 
    Name="$(var.ProductName)" 
    Version="$(var.ProductVersion)" 
    Manufacturer="$(var.CompanyName)" 
    Language="1033" 
    UpgradeCode="<upgrade code>">

I've posted the code for in on CodePlex: http://wixfileversionext.codeplex.com/

Chris Kaczor
  • 584
  • 3
  • 5
  • Does your extension still work? I tried adding it as a reference and I got an error. – Stefan Vasiljevic Jun 25 '14 at 20:01
  • This extension worked great with Wix 3.5, after updating to Wix 3.9 it throws a NullPointerException. Obviously something broke in between these versions. – Gigo Jul 13 '15 at 15:36
  • 2
    @Gigo I got it working via `` Where `FileId` is the value of the `Id` attribute of one of your `File` elements inside a `Component`. – Jesus is Lord Jan 26 '16 at 05:00
  • The CodePlex link is not opening for me. Is there any other way except writing your own pre-processor extension? – RDV Dec 04 '19 at 19:15
25

Here's a very simple way to get your Bootstrapper Bundle Version to match your MyApp AssemblyVersion using a BeforeBuild Target and DefineConstants.

Bundle.wxs:

<Bundle Name="$(var.ProductName) Bootstrapper v$(var.BuildVersion)"
     Version="$(var.BuildVersion)"

Bootstrapper.wixproj:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="..\MyApp\bin\$(Configuration)\MyApp.exe">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
  </GetAssemblyIdentity>
  <PropertyGroup>
    <DefineConstants>BuildVersion=%(AssemblyVersion.Version)</DefineConstants>
  </PropertyGroup>
</Target>
Brock Hensley
  • 3,617
  • 2
  • 29
  • 47
  • @AliKazmi Have you defined your `var.ProductName` and `var.BuildVersion` somewhere above your ``? – Brock Hensley Mar 27 '14 at 13:05
  • 3
    I tried this and cannot recommend this enough - combine it with the assembly patcher for TeamCity and you have got a winning formula. I did not use the Bundle element but a product element instead and still worked for me. – IbrarMumtaz Oct 24 '15 at 10:21
  • VS just loves to ignore `BeforeBuild` target so it might be necessary to specify explicitly `AfterTargets="AfterResolveReferences"` if you're building in the IDE – Dmitry Sep 04 '17 at 12:20
  • I added the Bootstrapper.wixproj code in my *.wixproj and in Product.wxs file, I defined the buildversion variable as: – RDV Dec 04 '19 at 23:26
  • unfortunately it doesn't work for .NET Core – Stepagrus Mar 07 '23 at 10:55
9

You can pass the version to the MSBuild script for your setup project the same as you can pass for application's build script.

For example, if your CI system defines variables AppVersion and BuildNumber, and passes them to your MSBuild scripts, your wixproj can create a corresponding Version property which it forwards to Wix like this:

<PropertyGroup>
    <Version Condition=" '$(BuildNumber)' == '' ">0.0.1</Version>
    <Version Condition=" '$(BuildNumber)' != '' ">$(AppVersion).$(BuildNumber)</Version>
    <DefineConstants>Version=$(Version)</DefineConstants>
</PropertyGroup>

The first definition of Version provides a default for when you're building locally. Whatever it ends up with becomes a Version variable in Wix. Use it in a wsx file like this:

<Product Version="$(var.Version)" ...>
    <Package Description="$(var.ProductName) $(var.Version): $(var.ProductDescription)" ... />

I like to include the version in the description so that it's easy to look up from Window Explorer (as a column in Detail view or on the Properties page) independent of the file name.

Passing the version as a variable gives you more control than reading it from a file. When you read from a file, you get all 4 parts of the programmatic version. However, ProductVersion is only designed to use the first 3 parts.

Edward Brey
  • 40,302
  • 20
  • 199
  • 253
  • Thanks, this saved my my day. BTW: The upper code snipped goes into yur project ( *.wxiproj). Having to manage a Devops/VSTS CI-Build this is the best answer. Since I already have my final version variable ready. It turned in my case to: `$(BuildVersionOfAsm)` while BuildVersionOfAsm is a variable in devops pipelines. – Robetto Aug 28 '19 at 11:12
  • I want to pick Version dynamically, this method will require me to keep on updating the version in *.wixproj. Is there a way to any dll's version in this field? – RDV Dec 04 '19 at 20:37
  • @RDV The intent with this approach is not change any files in source control, including the .wixproj. The dynamic version number is provided by your CI system (AppVersion and BuildNumber in this example). Typically, you set the major and minor version numbers as CI variables and let the CI system generate the build number dynamically. – Edward Brey Dec 05 '19 at 18:19
  • Excellent - just the kind of solution I needed, including a default for local builds. – ColH Mar 07 '20 at 11:49
4

This looks reasonably close to what you are trying to accomplish. See what the equivalent is in cruise control.

http://www.ageektrapped.com/blog/setting-properties-for-wix-in-msbuild/

JohnW
  • 2,982
  • 1
  • 28
  • 30