Cross-Link: Similar answer and short version. And the older: I screwed up, how can I uninstall my program?
Suppress Dialog: If that dialog is shown without a proper condition then no, you can not suppress it outright, but there are many workarounds. See list of "fixes" below.
Stuck Uninstalls: First some comments on stuck uninstalls (hanging / stuck or rolling back). There are several ways you can get stuck and here are just a few:
- Faulty Conditions: Faulty conditions can show dialogs erroneously or run custom actions during uninstall that should not run. Respectively this typically means stuck uninstall (dialog) or an uninstall that fails and rolls back (CAs). A dialog gets you stuck when running silently and it will also halt an interactive major upgrade (you must dismiss the dialog manually or the major upgrade will sit there waiting). To make matters worse the dialog can show up underneath other desktop windows.
- Other Catch 22s: A few other causes of failed uninstalls are possible.
- The prior uninstall of a shared runtime required by your own custom actions is one. This could be a version of the .NET framework, the VC Runtime, or anything you depend on that is already gone by the time you invoke your own uninstall. The CAs fall over and the setup rolls back.
- I have also seen Launch Conditions act up and prevent setup launch if they check for the presence of a missing prerequisite! Essential catch 22! For example: the .NET framework 2.0 is missing - which your app needs, but the uninstall does not - and this causes the setup to fail to uninstall as Launch Conditions are not met. Who decided to make launch conditions work like this on uninstall too? The WiX guys to the rescue with the
(OR Installed)
trick (this causes launch conditions to always be true when the setup is already installed).
"Fixes": There are some "fixes" of varying degrees of "insanity" for failing or stuck uninstalls (generally for the failing ones where custom actions cause the uninstall to roll-back and fail to complete - a catch 22 situation where you can't go forwards or backwards).
1)
MS FixIt: There is a Microsoft FixIt tool that sometimes allows you to get rid of stuck installs (not sure if it
applies to dialogs from custom actions). Try this first if you have
one or just a few instances.
2)
Minor Upgrade / Patch: Patch the existing installation with a minor upgrade
(preferred approach) - Chris Painter's answer. This can also be used "large scale" to fix a broken MSI's uninstall sequence which can then be invoked on all machines. The real fix if you like (once the problem is there on a large scale with many machines affected). There are some challenges in logistics. Corporations with distribution systems can usually incorporate a patch as part of upgrade installations pretty easily. They might not be too happy about it though :-).
3)
Transform: Hack apply a transform
that is then applied during uninstall (not recommended - too involved for comfort, error prone).
4)
Dr.No No: If there are few instances you can hack the locally cached MSI database
(basically the same that happens via a patch, only done manually).
- Works if you got a handful of machines (say 1-5 machines to clean up). You can use the Orca tool from the MSI SDK.
- Support job - not without risk! Not recommended.
And don't delete custom actions! Just add a condition "AND 0" to the offending custom action sequencing - that will stop the custom action from running
.
5)
MSI API: I rely on minor upgrade patching to fix things. However, it should be possible to modify the installed MSI via MSI API automation to change a few things in the locally, cached MSI to allow uninstall. Essentially an automated version of the previous "hack local MSI approach". Somewhat insane to try, but not impossible on paper (beware of looking like malware and ruining your trust gained by SmartScreen! - many vendors struggle with their product detected as false positive malware - it is horrendous to deal with and can ruin your product's reputation). The changes could be done via an executable included in your setup.exe
and launched prior to the installation of your new MSI (the new MSI on its own run without the setup.exe
will still fail). Remember that all fixes add new sources of bugs! (my fix for my failed fix failed, etc...).
6)
Lunacy: Some use tools from "stranger shores" - such as AutoIt which simulates keystrokes to dismiss stuck dialogs. Not at all good enough large-scale, but might work for smaller scenarios. Not recommended. Try tools like these against security software! Oh no! (anything can happen, it WILL break - just a matter of time).
Conditions: You should never show a dialog from a custom action sequenced in the InstallExecuteSequence
, though you can control its display using the UILevel property. You can add such a condition to the MSI using approaches 1-3 above. (NOT UILevel = 2
can be tried. Level 2 is completely silent running)
Suppress Failing Custom Actions: When uninstall is prevented by failing custom actions (as opposed to rouge dialogs), you could resort to an "inoculation method". You can update your package to be able to suppress custom actions via a command line switch which sets a specific property as a flag:
msiexec.exe /x {PRODUCT-GUID} SUPPRESSERROR="1"
See this WiX sample, or the mockup below (slightly different, but the same concept):
Adding Condition:
Quick mock-up for how to add a conditioned custom action to the InstallExecuteSequence
:
<Property Id="FLAG" Value="1"/>
<..>
<CustomAction Id='Something' Property='INSTALLFOLDER'
Value='[CMDLINE_INSTALLFOLDER]' Execute='firstSequence' />
<..>
<InstallExecuteSequence>
<Custom Action='Something' Before='AppSearch'>NOT Installed AND FLAG</Custom>
</InstallExecuteSequence>
With this approach all custom actions can be suppressed from running by invoking this kind of customized msiexec.exe command. Hence problematic custom action during uninstall or upgrade can be suppressed. This is just an "emergency method" to get something uninstalled.
I guess I should make the condition NOT Installed AND FLAG="1"
. Didn't test that, leaving in what is there.
Here is a similar, previous answer: Suppress custom actions on uninstall.
Some Similar or Related Answer: