A while back I posted a guide on how to get WiX to automatically set the installation package’s version, and how to rename the output package to include the same version number.

The instructions still work great, but it all felt a bit too messy.

I’ve spent a bit of time with WiX 3.5 over the last few days (because only WiX 3.5 beta supports Visual Studio 2010), and I’ve been able to solve a few niggling issues with my previous installers. Cleaning up how I name the output package is one of those.

I’m still doing this for the version number of the installer, (where $(var.xx.TargetFileName) points to a Project Reference*):

<Product Id="some-guid-here"
       Name="Blackbox for Windows Home Server"
       Language="1033"
       Version="!(bind.FileVersion.$(var.HomeServerConsoleTab.Blackbox.TargetFileName))"
       Manufacturer="Tentacle Software Ltd."
       UpgradeCode="some-guid-here">

But I’m now using a different method to rename the actual output file to include the version number, and have that automatically update whenever the version of the project changes.

The basic issue was that I couldn’t work out how to make the WiX processors pick up changes to the OutputName property of the wixproj file, so I was left with running an action after the build to rename the output file to what I wanted.

The old and busted way:

<Target Name="AfterBuild">
  <GetAssemblyIdentity AssemblyFiles="..\HomeServerConsoleTab.DiskMgt\bin\$(Configuration)\HomeServerConsoleTab.DiskMgt.dll">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersion"/>
  </GetAssemblyIdentity>
  <Copy SourceFiles=".\bin\$(Configuration)\$(OutputName).msi" DestinationFiles=".\bin\$(Configuration)\WHSDiskManagement.%(AssemblyVersion.Version).msi" />
  <Delete Files=".\bin\$(Configuration)\$(OutputName).msi" />
</Target>

The new hotness:

<Target Name="BeforeBuild">
  <GetAssemblyIdentity AssemblyFiles="$(SolutionDir)HomeServerConsoleTab.Modus\bin\$(Platform)\$(Configuration)\HomeServerConsoleTab.Blackbox.dll">
    <Output TaskParameter="Assemblies" ItemName="AssemblyVersions" />
  </GetAssemblyIdentity>
  <CreateProperty Value="$(OutputName).%(AssemblyVersions.Version)">
    <Output TaskParameter="Value" PropertyName="TargetName"/>
  </CreateProperty>
  <CreateProperty Value="$(TargetName)$(TargetExt)">
    <Output TaskParameter="Value" PropertyName="TargetFileName"/>
  </CreateProperty>
  <CreateProperty Value="$(TargetDir)$(TargetFileName)">
    <Output TaskParameter="Value" PropertyName="TargetPath"/>
  </CreateProperty>
</Target>

You can see I’m still using GetAssemblyIdentity and pointing to the assembly whose version number I want to grab, but I’ve switched to a BeforeBuild action. That’s because I figured out I could explicitly change the command parameters that WiX was sending – specifically, the TargetName, TargetFileName, and TargetPath variables, which determine the final file name of the package.

In the example above, I’m taking the OutputName that I configured in the project properties (“TentacleSoftware.Blackbox” in this case), and appending the version number to it to create my new TargetName.

There’s a few more lines of XML there, but basically after we set the TargetName property we’re just rebuilding the TargetFileName and TargetPath properties to match.

Interestingly, my initial tests showed that I didn’t have to update anything except the TargetName – the TargetFileName and TargetPath were still the ‘incorrect’ values but the output file included the version number anyway – but to be on the safe side, I’ve chosen to rebuild all the Target* properties so that they’re valid.

That all feels lots cleaner to me. We’re actually setting the desired output name and letting WiX take care of the rest, rather than renaming files at the end.

*More about Project References, and why I should have been using them ages ago, soon.

posted on Thursday, August 05, 2010 9:20 PM | Filed Under [ Windows Home Server Development ]

Comments

Gravatar
# re: Automated installer version numbers for WiX, revisited (peter kelly @ 8/11/2010 4:14 AM)

Good blog - enjoyed the first in the series too.

This is not working for me though...maybe you can help if you have a few minutes.


"The expression "@(_OutputPathItem->'%(FullPath)')DUC.WiX.Setup.1.9.1.0.msi" cannot be used in this context. Item lists cannot be concatenated with other strings where an item list is expected. Use a semicolon to separate multiple item lists."
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Sam Wood @ 8/11/2010 9:33 AM)

Hi Peter,

Can you post the chunk of XML that's throwing the error? Also, which version of WiX are you using?

 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Anna @ 10/29/2010 9:37 PM)

Cool post. the new method works fine.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (motoplux @ 12/3/2010 6:02 AM)

Great post.
Sadly GetAssemblyIdentity AssemblyFiles= isn't working for me, I think because my project is written in C++, and I'm filling files info with an .rc file, not with a manifest file-
Do you know if there is some different tag for wixproj xml that I can use?
Or something similar to !(bind.FileVersion. that is working good inside the .wxs?
Or also some way to import variable that I have defined in a header file, in which I have written the versioning number.
Thanks in advance.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Marcel @ 4/8/2011 12:22 AM)

For future reference if anybody else is running into the same issue as described by Peter (as I was).

I had to change the last CreateProperty element to use $(OutDir) instead of $(TargetDir) to make it work.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Filippo Bottega @ 9/3/2011 2:46 AM)

Great post!
Do you know if is possible to append to output file the culture? I'm creating a multilanguage setup and I'd like to get an output file name like:

"MyProduct 1.0.0.0 en-us.msi"

Thanks in advance,
Filippo.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Torpederos @ 10/11/2011 9:04 PM)

Marcel is right, changing $(TargetDir) to $(OutDir) works for me to.

Post Comment

Title *
Name *
Email
Url
Comment *  
Remember me
Please add 1 and 2 and type the answer here: