Skip to main content

Patchwork

It wouldn't be terribly effective to create an upgrade installation package with megabytes of files in it just because one or two small files inside have to be renewed. In cases like this, patching has always been a better solution. Patches basically contain the difference between the old and the new versions and can automagically turn the old file on the user's computer into the new one. Patch packages can also contain new files to be deployed.

The WiX toolset can also create patch installation packages (.msp files). These are created from two normal installation packages: the original one with the old, erroneous files and a new one with the fixed files. In the downloadable SamplePatch we have two very simple installation packages, without user interface. Both install a single file that will change between the original and patched versions. The details of the source files must be completely familiar by now. Our Error.wxs and Fixed.wxs source files will only differ in their Source file references:

  <File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1' Source='Error\FoobarAppl10.exe' KeyPath='yes' />

versus

  <File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1' Source='Fixed\FoobarAppl10.exe' KeyPath='yes' />

The patch will be created from a third source file. It is, just like the earlier ones, an XML file but the contents are different from the files we've created so far:

<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
  <Patch AllowRemoval='yes' Manufacturer='Acme Ltd.' MoreInfoURL='www.acmefoobar.com'
    DisplayName='Foobar 1.0.1 Patch' Description='Small Update Patch' Classification='Update'>
 
    <Media Id='5000' Cabinet='Sample.cab'>
      <PatchBaseline Id='Sample' />
    </Media>
 
    <PatchFamily Id='SamplePatchFamily' Version='1.0.0.0' Supersede='yes'>
      <ComponentRef Id='MainExecutable' />
    </PatchFamily>

  </Patch>
</Wix>

The Classification attribute can be Hotfix, Security Rollup, Critical Update, Update, Service Pack or Update Rollup. AllowRemoval decides whether the user can later uninstall the patch or not.

A PatchFamily tag encompasses the items to be patched. Supersede decides whether this actual patch supersedes all previous patches in this same family.

Building will be a little bit more complicated than our previous projects. First, we build the two base packages the usual way. Both will go into its own folder:

candle.exe Error.wxs
light.exe -out Error\Product.msi Error.wixobj

candle.exe Fixed.wxs
light.exe -out Fixed\Product.msi Fixed.wixobj

Then we use another WiX tool, torch to create a transform between the two installation packages. The command line arguments instruct the program to use WiX's own formats, .wixpdb and .wixmst rather than those of Windows Installer (.msi and .mst).

torch.exe -p -xi Error\Product.wixpdb Fixed\Product.wixpdb -out Patch.wixmst

We also have to build our patch package using the usual WiX compiler and linker but this time, the output format will be different from the usual one, .wixmsp. There is no need to tell the linker to produce this kind of file, it will determine it automatically based on the contents of the source file.

candle.exe Patch.wxs
light.exe Patch.wixobj

And finally, we build the actual Windows Installer patch package from the result of the previous step and the transform we created a while ago. Pyro, the WiX tool responsible for patch creation needs not only the name of the transform file but the corresponding PatchBaseline/@Id attribute as well on the command line:

pyro.exe Patch.wixmsp -out Patch.msp -t Sample Patch.wixmst

The Patch.msp will be the patch installer actually distributed. To test it, first install the original package (Error/Product.msi), then add the patch:

msiexec /p Patch.msp

... and check that the file has indeed been changed to the new version. Then, go into Add and Remove Programs, allow it to Show Updates, and remove first the patch (the changed file will revert back to the original one) and then the program itself.

An administrator can update the administrative source image located at //server/Patch.msi to a new source image that is the same as would be produced by an administrative installation from a fully updated distribution media.

msiexec /a //server/Patch.msi /p Patch.msp

Members of the workgroup using the program then must reinstall the application from the new administrative source image to receive the update. To completely reinstall the applications and cache the updated .msi file on the user's computer, users enter:

msiexec /fvomus //server/Patch.msi

Patchwork

I have used this method with no issues before, however, I have recently come across an issue where if the file I am looking to update with my minor upgrade patch has been updated by a patch before the one that I am looking to deploy, then that file does not get updated.
A clearer scenario is in the edited excpert from http://msdn.microsoft.com/en-us/library/windows/desktop/aa370841(v=vs.85).aspx below...

  1. Install RTM version of the product (Example.msi)
  2. Apply patch ExampleUpdater1.msp to the computer. This patches version 1.0 of Example.dll to version 1.1.
  3. A new patch, ExampleUpdater2.msp is provided, which updates Example.dll to version 1.2 and obsoletes ExampleUpdater1.msp. However, the patch was only created to target version 1.0 of Example.dll because it was generated using the RTM version of the product (Example.msi). Example.dll version 1.2 includes the fix contained in Example.dll version 1.1 (hence it obsoletes ExampleUpdater1.msp), but the .msp file was generated between the RTM and ExampleUpdater2 images. So, when ExampleUpdater2.msp is applied to the computer, only the files that are original on the computer, i.e. files that haven't been updated before, are updated. Example.dll is therefore not updated and kept as version 1.1

How does one solve this issue (seemingly, the installer only updates the original version of the files)?

Help on creating the WixMSP file

Hi,
I am trying to create a patch using WIX and followed your documentation.  I dont see the PAtch.wixmsp file created anywhere.  After running light.exe I see a .PCP and WixPDB file.  I also tried the following commaind:

Light.exe PatchInfo.wixobj -out PatchInfo.wixmsp
This does create a WisMsp file but it seem to be in a binary format and not readable. 
Any help on this is highly appreciated.  I am really stuck at this stage. 
PS:  I also tried MsiMSP.exe fro Wix2, but that also fails to consume the PCP file created using the new version of light.exe.
Thanks
Guru

You will need to WiX toolset

You will need to WiX toolset version 3.0.3001.0 or above.