In this blog post, I will provide an overview on what you can do with the new patch uninstall custom actions and how they work. The hope is that by understanding how patch uninstall custom actions work you will be able to put this new custom action type to use easily.
Why Patch Uninstall Custom Actions?
If a patch carries a custom action or carries any updates to a custom action then, that updated custom action is not run when uninstalling the patch. Also, a custom action does not get the information associated with the patch that is being uninstalled. You can look at the attached PPT to get a high level overview of the problem and the way Windows Installer has addressed it in Windows Installer 4.5
How to use this new custom action type?
A custom action that wants to run during patch uninstall will mark itself with a new msidbCustomActionTypePatchUninstall attribute. This attribute can be specified in the ExtendedType column of the CustomAction table. This new column is of type DoubleInteger and can be added when releasing a patch. A custom action marked with this attribute will run only when a patch is being uninstalled.
a. This attribute can be part of the original MSI. But, this attribute should not be dropped or added by a patch to an existing custom action. Altering this attribute in a patch on an existing custom action will cause patch uninstall to fail.
b. A new custom action with this attribute can be added by a patch.
c. When running a patch uninstall custom action, Windows Installer will use the custom action provided in the patch being uninstalled.
d. Windows Installer will make the updates within the patch being uninstalled available to the patch uninstall custom action.
Walkthroughs
Walkthroughs in this section are aimed at understanding several key scenarios associated with this feature. Each walkthrough will discuss what occurs when certain events are triggered. They however, do not discuss the “how”. Walkthroughs try to provide a reason on why certain behavior is appropriate and why certain tradeoffs were made.
In Stream RTM Patch Uninstall Custom Action
i. It has a patch sequence (as authored in the MsiPatchSequence table) number of 1.0.2.0.
ii. It replaces RTMCA1.exe in the binary table with Q1CA1.exe.
i. It has a patch sequence number (as authored in the MsiPatchSequence table) of 1.0.1.0.
ii. It replaces RTMCA1.exe in the binary table with Q2CA1.exe.
This walkthrough summarizes three behaviors:
While the above walkthrough takes an EXE custom action as an example, the behavior applies to even DLL and script custom actions.
On Disk Patch-Added Patch Uninstall Custom Action
Action
Sequence Number
InstallFiles
900
PatchFiles
1050
Q1CA
1000
Q1CADeferred
1005
Q2CA
850
i. Q2CA. This runs FTK.exe 1.2 because the files have not been updated by the patch uninstall operation yet.
ii. InstallFiles
iii. PatchFiles
iv. Q1CA. This also runs FTK.exe 1.2 because the files have not been updated by the patch uninstall operation yet.
v. Q1CADeferred. This will queue the custom action to run during script execution.
vi. During script execution, FTK.exe 1.0 will be run because the files have been updated by now.
This walkthrough summarizes the behavior that sequence numbers are important for patch uninstall custom actions that rely on non-“Binary Table” resources. Just like any standard custom action, based on when they are executed, they get different versions of the custom action.
Note that this behavior is applicable to DLL and script custom actions as well.
Patch Uninstall Custom Actions’ Ability to Access Install State
RTMCA
i. DeferredQCA is a patch uninstall deferred DLL custom action and
ii. RollbackQCA is a patch uninstall rollback DLL custom action.
i. Adds a new component C. This results in the following changes:
· A new component added to the Component table.
· A new component-feature mapping in the FeatureComponents table.
· A new registry key associated with the component results in a new entry in the Registry table.
ii. Changes an existing file. This results in:
· A change in file version of an existing file in the File table.
DeferredQCA
1010
RollbackQCA
1011
Table
Column
Row
Data
Current
File
Version
BlueFile
1.2.0.0
1.0.0.0
Component
Condition
C_PS_QFE2
NULL
Attributes
2
ComponentId
{88838DDB-DA25-4C4A-B221-E2BAC0305975}
Directory_
PATCHSEQFOLDER
KeyPath
QFE2
INSERT
FeatureComponents
F_PS_StdColor,C_PS_QFE2
Registry
Name
Value
QFE2-Simple1
Component_
Key
SOFTWARE\Microsoft\MsiTest\PatchSequencing
Root
-1
RTMCA would query this table to identify the component that was originally added by this patch will be dropped due to this patch uninstall. Based on this information, it can make any decisions that it has to. It needs to be noted that any modifications made to this table will be ignored and not used by Windows Installer in any way. The purpose of this table is for a patch uninstall custom action to make its decisions off of the patch being uninstalled and the state of the machine.
Implicit Patch Uninstalls
The patch sequence numbers for the above three patches are:
Patch
Patch Family
SP1
Fam1
1.1.0.0
Fam2
Q1
1.1.1.0
Q2
1.1.2.0
[Author: Hemchander Sannidhanam]This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.