Microsoft has had a long-standing policy of providing cumulative service packs – service packs that can be installed for a product whether a previous service pack for that product has been installed or not. Prior to the release of Windows Installer 3.1, minor upgrades which typically serve as service packs had to contain a pair of transforms for every servicing level including the original product (RTM) and all previous service packs (SPs) – perhaps even beta service packs. This not only increases time to create a patch since you’ll have ever-increasing numbers of pairs of target and upgrade .msi files, but also increases the patch size because of all data contained in the patch transforms.
It’s not enough to have a single transform pair target the product RTM because of how patch sequencing works. Whether using obsolescence or supersedence, minor upgrades are still considered in the applicable view of the product, namely when comparing the target ProductCode and ProductVersion properties with the actual ProductCode and ProductVersion properties currently installed on the machine – even when installing multiple patches at once, which is supported starting in Windows Installer 3.0. Consider the following abridged log from a multi-patch installation scenario with SP1 and SP2, both targeting the RTM.
MSI (c) (A4:84) [10:03:36:693]: SequencePatches starts. Product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, Product version: 1.0.0, Upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}, Product language 1033
MSI (c) (A4:84) [10:03:36:693]: 3.0 patch sp1.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.1.0
MSI (c) (A4:84) [10:03:36:693]: 3.0 patch sp2.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.2.0
MSI (c) (A4:84) [10:03:36:693]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp1.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}
MSI (c) (A4:84) [10:03:36:693]: Validating transform ‘T1ToU1’ with validation bits 0x922
MSI (c) (A4:84) [10:03:36:693]: Transform ‘T1ToU1’ is valid.
MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: minor upgrade patch sp1.msp is applicable.
MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp2.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.1.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}
MSI (c) (A4:84) [10:03:36:713]: Validating transform ‘T1ToU1’ with validation bits 0x922
MSI (c) (A4:84) [10:03:36:713]: Note: 1: 2749 2: T1ToU1 3: C:DOCUME~1USERLOCALS~1Temp17bad5.msp 4: 1.0.0 5: 1.1.0
MSI (c) (A4:84) [10:03:36:713]: 1: 2749 2: T1ToU1 3: C:DOCUME~1USERLOCALS~1Temp17bad5.msp 4: 1.0.0 5: 1.1.0
MSI (c) (A4:84) [10:03:36:713]: PATCH SEQUENCER: minor upgrade patch sp2.msp is not applicable.
MSI (c) (A4:84) [10:03:36:713]: SequencePatches returns success.
MSI (c) (A4:84) [10:03:36:713]: Final Patch Application Order:
MSI (c) (A4:84) [10:03:36:713]: {D34AA461-D159-48E5-908B-62F565F303E4} – sp1.msp
MSI (c) (A4:84) [10:03:36:713]: Other Patches:
MSI (c) (A4:84) [10:03:36:713]: UnknownAbsent: {4B45E0A7-7D85-410B-9D3F-E5DF343BFF95} – sp2.msp
Rather than fail the entire installation when installing multiple patches,
only applicable patches are applied. If you installed SP1 then SP2 in succession,
Windows Installer would return ERROR_PATCH_TARGET_NOT_FOUND
(1642)
when attempting to install SP2. The reason is that SP1 is still applicable when
calculating supersedence. To remedy this situation, SP2 would require transforms
from the SP1 servicing level to SP2. This can be done by either building the RTM
up to look like the SP1, or creating what we call a “service release”, or SR,
which is essentially an administrative installation with a minor upgrade
applied.
The advent of Windows Installer 3.1 introduced an easier way, however, that actually supersedes all previous patches before the final supersedence is even calculated: the MinorUpdateTargetRTM property in the patch package’s MsiPatchMetadata table.
With this property present in the MsiPatchMetadata table of SP2 in our example, only a single pair of transforms are necessary to target the product RTM. This means that generating a number of transforms for every possible target is not necessary, and when you consider that we elease beta SPs this number can grow quite rapidly. Take a look at the difference in the abridged log below where the only change was adding the MinorUpdateTargetRTM property into the MsiPatchMetadata table for SP2.
MSI (s) (F0:48) [11:12:57:664]: SequencePatches starts. Product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, Product version: 1.0.0, Upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}, Product language 1033
MSI (s) (F0:48) [11:12:57:664]: 3.0 patch sp1.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.1.0
MSI (s) (F0:48) [11:12:57:664]: 3.0 patch sp2.msp of type minor upgrade takes product {1E37580C-4EC8-4CF1-A887-651D8AD74177} to version 1.2.0
MSI (s) (F0:48) [11:12:57:664]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp1.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}
MSI (s) (F0:48) [11:12:57:664]: Validating transform ‘T1ToU1’ with validation bits 0x922
MSI (s) (F0:48) [11:12:57:664]: Transform ‘T1ToU1’ is valid.
MSI (s) (F0:48) [11:12:57:674]: PATCH SEQUENCER: minor upgrade patch sp1.msp is applicable.
MSI (s) (F0:48) [11:12:57:674]: PATCH SEQUENCER: verifying the applicability of minor upgrade patch sp2.msp against product code: {1E37580C-4EC8-4CF1-A887-651D8AD74177}, product version: 1.0.0, product language 1033 and upgrade code: {8166E0CB-2A4E-46DD-ADF0-A0DD5C0BE48D}
MSI (s) (F0:48) [11:12:57:684]: Validating transform ‘T1ToU1’ with validation bits 0x922
MSI (s) (F0:48) [11:12:57:684]: Transform ‘T1ToU1’ is valid.
MSI (s) (F0:48) [11:12:57:684]: PATCH SEQUENCER: minor upgrade patch sp2.msp is applicable.
MSI (s) (F0:48) [11:12:57:684]: SequencePatches returns success.
MSI (s) (F0:48) [11:12:57:684]: Final Patch Application Order:
MSI (s) (F0:48) [11:12:57:684]: {4B45E0A7-7D85-410B-9D3F-E5DF343BFF95} – sp2.msp
MSI (s) (F0:48) [11:12:57:684]: Other Patches:
MSI (s) (F0:48) [11:12:57:684]: Superseded:
{D34AA461-D159-48E5-908B-62F565F303E4} – sp1.msp
You can have this property added to your patch by authoring it into the PatchMetadata table of your .pcp file to be processed by PatchWiz.dll. Unfortunately, PatchWiz.dll version 3.1 doesn’t consider the MinorUpdateTargetRTM property to be a standard property; that is, a property in the resulting MsiPatchMetadata table that does not require a value for the Company field. This is fixed for PatchWiz.dll version 4.0 that ships with the Windows Vista Platform SDK for beta 2 or newer, which can be used to create patches targeting older versions of Windows Installer.
If you cannot use PatchWiz.dll version 4.0 or newer for whatever reason, you can open the .msp package and add the property yourself rather easily, as developed in the sample script using the Windows Installer automation interface. Please note this script is only an example of how to programmatically add the MinorUpdateTargetRTM property and is not officially supported.
0 comments