Reputation: 369
I am using WiX 3.6 to create an msi that copies a few exe's and dll's, installs a number of windows services and adds and deletes a few registry entries.
WiX is brilliant and using it's built in features and custom actions in an associated .net managed dll I have been able to do everything I need to very easily.
One annoying problem has recently started happening though.
Installs proceed with no errors and do exactly what I expect, but when I uninstall, either from the Program Features control panel, or from a command line, the product entry remains in the Program Features list. All other files, services and folders are removed as expected, and the uninstall completes with no errors reported!
If I run the uninstall a second time, the Program Features entry is removed!
I have used verbose logging of the install and uninstall and viewed both through the Windows Installer Verbose Log Analyzer from the platform SDK, and it reports no errors.
I am puzzled!
I am sure it was uninstalling correctly before, but I cannot identify what I have done to make it start exhibiting this behaviour.
Any ideas would be appreciated.
PS I am running on Windows 7 64 bit machine, and generating a 32 bit installer.
PPS Log is too big to include here. Can anyone advise which entries I need to look at that controls the removal of the entry from the Program Features list?
Further clarification;
I had already checked the link from Christopher's answer below, but the situation did not match mine.
After the first uninstall, the entry disappears from the Program Features list but reappears in the list if it is refreshed or exit the control panel and come back to it. The registry entry is still present (I have checked) and so this is why it still appears in the list.
The second uninstall removes the entry from the registry, and thus from the list too.
Upvotes: 0
Views: 5050
Reputation: 369
I have retraced the changes I have made to the msi recently and have discovered the change I made that caused the uninstall to behave strangely.
I created a feature that deletes a few old registry entries, and I only needed to do that during the initial install, so I put a condition on the feature as follows;
<Feature Id="RegistryEntries" Level="0">
<Condition Level="1">(NOT Installed)</Condition>
<ComponentRef Id="RegKeysToDelete"/>
</Feature>
If I have no condition, the msi installs and uninstalls as expected.
With the above condition, it installs correctly and deletes the registry keys, but the uninstall leaves the entry in Add Remove Programs and I need to uninstall again to remove it fully.
If I use the following condition, the msi installs and uninstalls as expected;
<Feature Id="RegistryEntries" Level="0">
<Condition Level="1">(NOT Installed) OR REMOVE ~= "ALL"</Condition>
<ComponentRef Id="RegKeysToDelete"/>
</Feature>
I didn't cater for the uninstall initially because I don't need to do anything on uninstall with these registry keys. Although this fixes the issue I had, I don't understand why the first condition not evaluating to 1 causes the msi not to uninstall as expected, but I guess that is another question...
See the MSDN topic Condition Table (Windows) (Remarks Section)
Conditions should be carefully chosen so that a feature is not enabled on install and then disabled on uninstall. This will orphan the feature and the product will not be able to be uninstalled.
Upvotes: 3
Reputation: 55571
This isn't really an "answer" but a place to put some artifacts I see from your heavily redacted log:
First Run:
(STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: StartServices; Installed: Local; Request: Null; Action: Null
(STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: Configs; Installed: Local; Request: Absent; Action: Absent
(STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: Database; Installed: Local; Request: Absent; Action: Absent
(STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: RegistryEntries; Installed: Local; Request: Null; Action: Null (STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: Executables; Installed: Local; Request: Absent; Action: Absent (STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: Complete; Installed: Local; Request: Absent; Action: Absent (STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: Services; Installed: Local; Request: Absent; Action: Absent (STATE) MSI (s) (B4:3C) [09:18:48:395]: Feature: DLLs; Installed: Local; Request: Absent; Action: Absent
Second Run:
(STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: StartServices; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: Configs; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: Database; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: RegistryEntries; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: Executables; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: Complete; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: Services; Installed: Absent; Request: Null; Action: Null (STATE) MSI (s) (48:0C) [09:33:17:664]: Feature: DLLs; Installed: Absent; Request: Null; Action: Null
Bottom line is I'm not sure. The first log says that certain featues are installed and not being requested for removal. The second log says the features are not installed and no request is being made. I'm a little stumped as to how in the second log every feature can say it's not installed and yet we have an installation to remove.
Either this is something new I've never seen or the logs are so heavily redacted or not representitive of the situation that they are accidentally misleading.
Upvotes: 0
Reputation: 55571
It's a bug in Add/Remove Programs (Windows Shell team). If you close or refresh ARP you should see your entry go away. There is likely nothing wrong with your MSI (Windows Installer Team).
Checkout:
Why does my program still show up in the Programs and Features folder after my uninstaller exits?
Here's a thread related to WiX:
BTW, you aren't actually running the uninstaller a second time. You are simply clicking on the uninstall button at which point ARP realizes "oh that doesn't exist anymore" and it gets removed. The uninstall doesn't actually get invoked.
Upvotes: 1