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.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (McDon @ 12/22/2011 11:28 AM)

You can also set the OutputName property when building the wixproj using msbuild. Below is the build target from my build script.

<Target Name="Build" DependsOnTargets="Clean">
<MSBuild Projects="@(WixSolution)"
Targets="Rebuild"
Properties='Configuration=Release;OutputName=Custom Install Name'/>
</Target>
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (tim @ 4/13/2012 7:12 AM)

It worked out of the box for me.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Michael @ 6/11/2012 8:19 PM)

Simply amazing piece of information saving us a lot of time. Cheers!
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Brandon @ 9/26/2012 4:10 AM)

Fantastic! Exactly what I was looking for and elegant too.
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Ken Beckett @ 9/30/2012 5:58 AM)

Works great! Although, in my case, I very much prefer only the Major and Minor version numbers on the output file name, like this:

$(OutputName).%(AssemblyVersions.Version.Major).%(AssemblyVersions.Version.Minor)

This results, for example, in "4.35" instead of "4.35.4647.27625".
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Ken Beckett @ 9/30/2012 6:28 AM)

Sorry, my suggestion for getting only the Major.Minor version doesn't actually work at all as I posted it. To get it to work, I had to do this:

<CreateProperty Value="%(AssemblyVersions.Version)">
<Output TaskParameter="Value" PropertyName="TargetVersion" />
</CreateProperty>
<CreateProperty Value="$(OutputName).$(TargetVersion.Split('.')[0]).$(TargetVersion.Split('.')[1])">
<Output TaskParameter="Value" PropertyName="TargetName" />
</CreateProperty>
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Ahmed Patel @ 2/6/2014 12:08 AM)

Great Article! Helped me on a few projects, thanks!

@Ken Beckett, thanks for the comment for getting a 2 part version number too. I've adapted it to use a 3 part version for myself.

<Target Name="BeforeBuild">
<GetAssemblyIdentity AssemblyFiles="$(SolutionDir)MyProject\bin\$(Configuration)\MyProject.exe">
<Output TaskParameter="Assemblies" ItemName="AssemblyVersions" />
</GetAssemblyIdentity>
<CreateProperty Value="%(AssemblyVersions.Version)">
<Output TaskParameter="Value" PropertyName="TargetAssemblyVersion" />
</CreateProperty>
<CreateProperty Value="$(TargetAssemblyVersion.Split('.')[0]).$(TargetAssemblyVersion.Split('.')[1]).$(TargetAssemblyVersion.Split('.')[2])">
<Output TaskParameter="Value" PropertyName="TargetVersion" />
</CreateProperty>
<CreateProperty Value="$(OutputName).$(TargetVersion)">
<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>



 
Gravatar
# re: Automated installer version numbers for WiX, revisited (Landon @ 5/5/2014 10:40 PM)

Thank you for posting this. It was very helpful and works great!
 
Gravatar
# re: Automated installer version numbers for WiX, revisited (grmihel @ 3/4/2016 2:38 AM)

This blog post is quiet helpful.
But is it possible to make it even more generic/dynamic?
Is there a way to make:
<GetAssemblyIdentity AssemblyFiles="$(SolutionDir)HomeServerConsoleTab.Modus\bin\$(Platform)\$(Configuration)\HomeServerConsoleTab.Blackbox.dll">

more dynamic, so it reusable for several projects? By this I mean get the static part 'HomeServerConsoleTab-Modus' and 'HomeServerConsoleTab-BlackBox.dll' as values from the target project instead of hardcoded values?

This should result in automated dynamic (and reusable) wix project, naming your msi's as projectName_version.msi

Post Comment

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

Search

Site Sections

Recent Posts

Archives

Post Categories

WHS Add-In Tutorial

WHS Blogs

WHS Development