About Windows Installer, the .NET Framework, and Visual Studio.
Generally, small updates target a specific ProductVersion, and with Windows Installer 3.0 and newer minor upgrades should target the RTM ProductVersion using MinorUpdateTargetRTM in the MsiPatchMetadata table to support cumulative minor upgrades, which is a win for customers. What happens when a small update doesn't target a single ProductVersion?
First, how does a small update target a specific ProductVersion anyway? A Windows Installer patch, or .msp file, is little more than a container for transforms and upgrade files. Those transforms contain validation bits that determine if a transform can apply to a given product, based on ProductCode, ProductLanguage, ProductVersion, and UpgradeCode properties.
In the transform, the upper word consists of validation bits documented for the MsiCreateTransformSummaryInfo() function. Typically a small update will use validation bits 0x0923 or 0x0927 (0x4 is MSITRANSFORM_VALIDATE_PLATFORM, but is unused). A small update that bitwise ORs MSITRANSFORM_VALIDATE_NEWGREATEREQUALBASEVERSION (0x0200) will always sequence at the end of the patch application sequence. Because Windows Installer 3.0-style small updates, or patches with an MsiPatchSequence table, are first placed in the highest ProductVersion bucket before being superseded, they will apply at the end of the sequence after the highest minor upgrade. The only thing that could supersede this patch is another patch with the same transform validation bits and a higher sequence number in all patch families.
Thus, it is recommended that small updates apply to one particular baseline, that is either RTM or a minor upgrade, which may often be referred to as a service pack (SP), though that term is not standard in Windows Installer itself.
Now, if you have already shipped a superseding minor upgrade and need to target the RTM version of a product, you may need to create a small update using transform validation bits like 0x0a23. Be sure to leave room to supersede the small update in the MsiPatchSequence table.
Sorry Heath, I failed to get this approach to work. Here's what I did:
The RTM package installs version 0.9.3.7684.
A minor upgrade patch is applied, with a product version and sequence number of 0.9.4.7687. It has the "MinorUpdateTargetRTM" property set in PatchMetadata and the "SupersedeEarlier" flag set in the sequence attributes.
When attempting to apply a newer patch (targeted at the RTM version) with a product version and sequence number of 0.9.4.7696, the same properties/flags as above and the transform validation bits set to 0x0a22, that latest patch is detected as applicable, but superseded by the earlier minor upgrade, resulting in an unchanged installation.
Any ideas how the proper sequencing can be enforced here?
Best regards, Gerhard
Gerhard, Changes in the 4th field of ProductVersion are not used in sequencing calculations, and minor upgrades are sequenced according to what they change ProductVersion to. What you created in second case was a minor update. Use something like 0.9.5.7696 and it should work.