Fighting Windows Installer

The other day a simple question was asked on the WiX-Users mailing list:

…I would like to Create a “major” upgrade installer, even when only the
fourth field of the Product Version has changed.

To which Windows Installer defender and Microsoft employee Bob Arnson proclaimed:

“Doctor, it hurts when I do this.” You know the rest. It might be possible
to make it work but you’re fighting Windows Installer, which doesn’t support the
fourth field in a product version for upgrades.

Well considering the number of doctors that I’ve been to in the last year I know how I’d respond to that one. Time for a second opinion!

Sometimes working with Windows Installer is all about fighting Windows Installer. Don’t believe me? Check out the LockPermissions table for starters.

For some reason Microsoft decided that when following an a.b.c.d versioning pattern that a change of d just doesn’t qualify as a major upgrade. Why? It’s just a version number for heavens sake. That business logic is entirely too coupled. The decision to go with a major upgrade should be driven by the change in components and feature structure and servicing experience desired not by the version. If a minor upgrade won’t do the trick and SCM/Program Management says you are going from 1.0.100.0 to 1.0.100.1 well that’s that. You need a Major Upgrade.

As an aside, I never agreed with the definition of a Small Update. A Small Update is basically a Minor Upgrade ( change of PackageCode but not ProductCode ) with the exception the ProductVersion does not change. What?? The SCM practices of everywhere I’ve ever worked would never allow that. Once 1.0.100.0 is fielded it’s immutable. You must increment the version to show uniqueness. The only reason I can think of doing this is when you are trying to sneak a fast one under the radar.

Anyways, back to the question at hand: This is actually pretty easy to do. You just have to understand how FindRelatedProducts and RemoveExistingProducts work together. The former reads the upgrade table to know which products are to be searched for and which ActionProperty to put the data in. The later reads the table to know which property to expect to find the data in. The real work is performed by RemoveExistingProducts. A Type 51 custom a CA scheduled between the two would easily allow you to bend the business rules implemented but not exposed by FindRelatedProducts.

BTW, stay tuned to a future blog post where I point out how the .NET Framework install is a complete hack ( sorry, clever WiX based solution invented by Microsoft employees who should be worshipped ) that works against Windows Installer .

Seriously, what else could you call an empty MSI that is then patched with a full MSP and serviced by a bootstrapper and external UI handler just to get around the nasty database caching story that Windows Installer has. You know the one that strips out cabs and invalidates digital certificates causing annoying dialogs like “Please Insert The Stupid Media” and “Unkown Publisher”.