Tuesday, October 19, 2010

How to fix a hanging uninstaller

Summary: How to fix a hung uninstaller issue due to inclusion of Visual C or MFC runtime merge module in the MSI package.
I have hassled with this problem for a long time and just recently figured out how to fix it, so I'm posting the solution in hope that it will help someone else.

Symptoms
You create an MSI package using Visual Studio, WiX Toolset, or whatever. The MSI package works fine during initial installations, repairs, and upgrades, but it takes really long time to uninstall. It may take two minutes, five minutes, 15 minutes, or longer, when it should've taken a few seconds. In my last case, after 20 minutes of waiting I gave up and killed the MSIEXEC process (this was during testing, so no harm was done).

Troubleshooting
I suspect that an uninstaller can (appear to) hang for different reasons. If your setup package includes merge modules for any version of Visual C or MFC runtime, such as Microsoft_VC80_CRT_x86.msm, Microsoft_VC80_MFC_x86.msm, Microsoft_VC90_CRT_x86.msm, Microsoft_VC90_MFC_x86.msm, etc, they can cause the problem. To verify, build your MSI package without these merge modules and see if the uninstaller runs faster. If it does not, I'm sorry, I can't help you, but if your uninstaller runs significantly faster, you should be able to correct the problem. Another troubleshooting step could be running uninstaller for the MSI containing the merge modules with logging enabled and checking the log entries. The command line for this should be similar to:
msiexec /uninstall "PATH TO YOUR MSI FILE" /l*vx "PATH TO OUTPUT/LOG FILE"
In my log file, when the installer appeared hanging, I saw a repetition of the same pattern of log messages that looked like these:
Action start 13:07:24: SxsUninstallCA.
1: sxsdelca tried opening key w/o wow64key  2: Software\Microsoft\Windows\CurrentVersion\SideBySide\PatchedComponents 3: 380 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (235) of type 790531 for thread 200
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (236) of type 790531 for thread 200
1: sxsdelca tried opening wow64key  2: Software\Microsoft\Windows\CurrentVersion\SideBySide\PatchedComponents 3: 404 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (236) of type 790531 for thread 200
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (237) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 1158 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (237) of type 790531 for thread 200
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (238) of type 790531 for thread 200
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (239) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 1186 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (239) of type 790531 for thread 200
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (240) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 732 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (240) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 748 4: 0
MSI (s) (E8!C8) [13:07:24:507]: Creating MSIHANDLE (241) of type 790531 for thread 200
1: scavenge 2: {121634B0-2F4B-11D3-ADA3-00C04F52DD52} 3: {98CB24AD-52FB-DB5F-C01F-C8B3B9A1E18E} 4: {AEA1383C-9A90-406A-8CAE-718170D9CBDA} 5: -1
MSI (s) (E8!C8) [13:07:24:507]: Closing MSIHANDLE (241) of type 790531 for thread 200
...
...
...
MSI (s) (E8!C8) [13:16:37:663]: Creating MSIHANDLE (180783) of type 790531 for thread 200
1: scavenge 2: {EDDF99D9-9FE3-4871-A7DB-D1522C51EE9A} 3: {42CDEC6E-1259-F078-C01F-C8B3B9A1E18E} 4: {AEA1383C-9A90-406A-8CAE-718170D9CBDA} 5: -1
MSI (s) (E8!C8) [13:16:37:663]: Closing MSIHANDLE (180783) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 748 4: 0
MSI (s) (E8!C8) [13:16:37:663]: Creating MSIHANDLE (180784) of type 790531 for thread 200
1: scavenge 2: {0EFDF2F9-836D-4EB7-A32D-038BD3F1FB2A} 3: {42CDEC6E-1259-F078-C01F-C8B3B9A1E18E} 4: {AEA1383C-9A90-406A-8CAE-718170D9CBDA} 5: -1
MSI (s) (E8!C8) [13:16:37:663]: Closing MSIHANDLE (180784) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 748 4: 0
MSI (s) (E8!C8) [13:16:37:663]: Creating MSIHANDLE (180785) of type 790531 for thread 200
1: scavenge 2: {4D7B7CF9-E7EA-4404-B148-0C8B8A520E35} 3: {42CDEC6E-1259-F078-C01F-C8B3B9A1E18E} 4: {AEA1383C-9A90-406A-8CAE-718170D9CBDA} 5: -1
MSI (s) (E8!C8) [13:16:37:663]: Closing MSIHANDLE (180785) of type 790531 for thread 200
1: sxsdelca 2: traceop 3: 748 4: 0
Reason
I'm not quite certain why this is happening, but apparently the problem only occurs under certain conditions, i.e. the same MSI package that includes Visual C or MFC runtime merge modules may work fine on some systems and hang on others. For more information, check the See also section.

Solution
This may not be the most elegant solution, but in the absence of alternatives, to fix the problem, do not process Visual C and MFC runtime components during uninstallation. In the MSI terms, you need to delete the SxsUninstallCA action from the CustomAction table in the MSI package.

ActionTypeSourceTarget
SxsUninstallCA1SxsUninstallCACustomAction_SxsMsmCleanup

You can delete this record manually using Orca, but it would be more convenient to automate the operation, which you can do with the help of the WiRunSql.vbs script. The script comes with the Windows Installer Software Development Kit (SDK). Once you install the SDK, you can find the WiRunSql.vbs file in the location similar to:

C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\sysmgmt\msi\scripts\WiRunSQL.vbs

You can copy this file to your project or solution folder and then execute it as a post-build step. For example, if you keep the script in the solution folder, your post-build command in a WiX project may look like this (make sure the command appears on one line):

cscript //nologo "$(SolutionDir)WiRunSql.vbs" "$(TargetPath)" "DELETE FROM CustomAction WHERE CustomAction.Action='SxsUninstallCA'"

Enjoy!

See also:
WinForm app Uninstall involving VC++ runtime libs takes a long tim[e]

1 comment:

InstallAware said...

Thanks to Alek! Here I got the solution. I knew how to fix a hanging uninstaller. I have also gotten some Info about installation to view this blog.