But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Getting Wix 3.6 MajorUpgrade working

Why is everything so complex to get going with Wix, then so easy in the end when you get the syntax correct?

If you want to allow your MSI installer to upgrade a previous version then there are some things you have to have correct if you don’t want the ‘Another version of this product is already installed’ dialog appearing.

  • The Product Id should be set to * so that a new Guid is generated each time the product is rebuild
  • The Product UpgradeCode should be set to a fix Guid for all releases
  • The Product Version should increment on of the first three numbers, by default the final build number is ignored for update checking
  • The Package block should not have an Id set – this will allow it to be auto generated
  • You need to add the MajorUpgrade block to you installer

So you end up with

Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
  <Product Id="*" Name="My App v!(bind.FileVersion.MyExe)" Language="1033" Version="!(bind.FileVersion.MyExe)" Manufacturer="My Company" UpgradeCode="6842fffa-603c-40e9-bedd-91f6990c43ed">
    <Package InstallerVersion="405" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated"  />

    <MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />

……

So simpler than pre Wix 3.5, but still places to trip up

Running an external command line tool as part of a Wix install

I have recently been battling running a command line tool within a Wix 3.6 installer. I eventually got it going but learnt a few things. Here is a code fragment that outlines the solution.

<Product ………>
……… loads of other Wix bits

<!-- The command line we wish to run is set via a property. Usually you would set this with <Property /> block, but in this case it has to be done via a
       
CustomAction as we want to build the command from other Wix properties that can only be evaluated at runtime. So we set the
       whole command line  including command line arguments as a CustomAction that will be run immediately i.e. in the first phase of the MSIExec process  
       while the command set is being built.

     Note that the documentation say the command line should go in a property called QtExecCmdLine, but this is only true if the CustomAction
    is to be run immediately. The CustomAction to set the property is immediate but the command line’s execution CustomAction is deferred, so we
    have to set the property to the name of the CustomAction and not QtExecCmdLine  -->

<CustomAction Id='PropertyAssign' Property='SilentLaunch' Value='&quot;[INSTALLDIR]mycopier.exe&quot; &quot;[ProgramFilesFolder]Java&quot; &quot;[INSTALLDIR]my.jar&quot;' Execute='immediate' />

  <!—Next we define the actual CustomAction that does the work. This needs to be deferred (until after the files are installed) and set to not be impersonated
          so runs as the same elevated account as the rest of the MSIExec actions. (assuming your command line tool needs admin rights -->
  <CustomAction Id="SilentLaunch" BinaryKey="WixCA"  DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no" />
 
  <!—Finally we set where in the install sequence the CustomActions and that they are only called on a new install
          Note that we don't tidy up the actions of this command line tool on a de-install -->
  <InstallExecuteSequence>
   <Custom Action="PropertyAssign" Before="SilentLaunch">NOT Installed </Custom>
   <Custom Action="SilentLaunch" After="InstallFiles">NOT Installed </Custom>
  </InstallExecuteSequence>

 
</Product>

So the usual set of non-obvious Wix steps, but we got there in the end