Cumulative Patching with WiX 2.0

Sometimes I wonder if Windows Installer will be the death of me. While I’ve successfully shipped device drivers, debuggers, and all sorts of bizarre products, I have to say that trying to get something installed on Windows is one of the more frustrating things I have encountered in my career. I can’t be the only one who feels getting files onto a machine in the approved manner is far more complicated than it needs to be. The horrible state of most installations we deal with speaks to that. If I were a high enough at Microsoft I would stop all development on Windows Installer 4.5 and make the team provide example installers for all the common scenarios as well as provide documentation that doesn’t assume you’re an install guru. Of course all the examples and documentation would be using Windows Installer XML (WiX) since Visual Studio “Rosario” is shipping WiX. Sorry for the venting, but sometimes you just have to. <g>

For a project I’m using WiX 2.0 on, I wanted to release a 1.00 .MSI file and have all the updates be patches. The big trick was that I wanted to have a single cumulative patch file. Thus, if 1.00 was installed on the machine, I wanted a patch file that would install a 1.01 patch. As we released additional patches, I wanted the patch file to be able to update a 1.00 installation no matter what previous patches were on the machine. In other words, if 1.00 is on the machine and 1.01 and 1.02 patches were applied, but the 1.03 patch was skipped, by applying the 1.04 patch, the final result would be that the machine would have the equivalent of a 1.04 straight install. It seemed so simple, but given the number of people asking the same question all over the web, I got a little worried that anyone less than an install ninja would be able to get it working.

The WiX patching tutorial shows you how to get started and show you how to build a patch that updates a 1.00 install to a 1.01 install. However, if you follow the instructions to build a 1.02 patch, you’ll find that creating the patch with the 1.02 build against the 1.00 build works, but if you have applied the 1.01 patch, the install fails with an installation 1642. If you create a patch against build 1.01 to build 1.02, you would have a patch that works. However, you can quickly see that’s going to descend into complete chaos from a patch management perspective. I don’t want to maintain twenty or thirty admin installs to build patches against each one. Also, I’d have to write a boot strap SETUP.EXE to look what patch level was installed in order to install the patches in the correct order.

Quite a bit of experimentation and web searching later, I found the tricks I needed. Heath Stewart mentioned the MinorUpdateTargetRTM property which “indicates that the patch targets the RTM version of the product or the most recent major upgrade patch.” That sounded exactly what I was looking for. Once I added the attribute to my PatchMetaData element, the 1.02 installer updated both 1.00 and patched 1.01 installs. Note that MinorUpdateTargetRTM is only supported with Installer 3.1.

<PatchMetadata
Description=Acme’s Foobar 1.0.2 Patch
               DisplayName=Foobar 1.0.2 Patch
               TargetProductName=Foobar 1.0
               ManufacturerName=Acme Ltd.
               MoreInfoURL=www.acmefoobar.com
               Classification=Service Pack
               AllowRemoval=yes
               MinorUpdateTargetRTM=1 />

With my patching working in a test case, I got to wondering how you would create a patch that would remove files. Fortunately, Trent Mick had the exact answer. If you need to remove a file, in the Component element for that file in the updated main .WXS file, specify RemoveFile for the file like the following:

<

p style=”background:white;”><Component
Id=AnotherFile
           Guid=C7D97EA9-83DF-4B07-8E38-D10A30F70FD2>
<
RemoveFile
Id=RemoveFile
On=install
Name=NewFile.txt/>
</
Component>

Since I spent about six hours trying to figure all this out, I thought I’d share what worked for me.

John Robbins

View Comments

  • Kevin,
    Please give patches a try. :) Turns out on both XP and Vista, installing the patch is as simple as double clicking on the .MSP file. That worked every time for me.
    I should have said something in the entry. Sorry!
    -John.

  • Interesting post!
    Do you happen to know if there's a way to have a _single_ installer that:
    If the application was never installed -> installs the application from scratch
    If the application was installed -> applies a patch
    - J

  • Using .pcp, I have created patch(.msp) file. When I installing the patch, it is showing "Repair". But no changes are reflected.
    So I used Orca to view the changes. First , opened the targeted msi,
    then Transform->View Patch. In that, I can able to see the changed
    files. But after installing the patch, that wont be reflected.
    I cannot able to find the solution for this problem.
    Please advice.

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

4 days ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

2 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

4 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago