1

This seems really odd. I have a program installed (via a WiX installer) and I'm trying to uninstall it programatically (using c#) so I use msiexec.exe /x{product-code-GUID}. The program is uninstalled but it still shows in the control panel (add/remove programs). When I look in the registry I see the program under HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\, but it's not under the GUID that this product has as its product code. It's under a seemingly random GUID that doesn't even exist in the .msi. Anyone know why and how I can tell what the GUID will be so that I can programtically remove it?

I guess I could install each version that I need to uninstall and inspect the registry and use the GUID that's there. That will work, but I want to understand why the GUID doesn't match the Product Code.


UPDATE 2-15-19 9:21am PT:

OK - I logged the uninstall and here's the end of the log. It seems to have completed successfully and yet it still appears in Control Panel:

MSI (s) (10:E4) [09:16:22:812]: Note: 1: 1724 
MSI (s) (10:E4) [09:16:22:812]: Product: Product Name -- Removal completed successfully.

MSI (s) (10:E4) [09:16:22:812]: Windows Installer removed the product. 
Product Name: Product Name. Product Version: 1.21.4. Product Language: 1033. 
Manufacturer: . Removal success or error status: 0.

MSI (s) (10:E4) [09:16:22:870]: Deferring clean up of packages/files, if any 
exist
MSI (s) (10:E4) [09:16:22:870]: MainEngineThread is returning 0
MSI (s) (10:80) [09:16:22:871]: RESTART MANAGER: Session closed.
MSI (s) (10:80) [09:16:22:871]: No System Restore sequence number for this 
installation.
=== Logging stopped: 2/15/2019  9:16:22 ===
MSI (s) (10:80) [09:16:22:892]: User policy value 'DisableRollback' is 0
MSI (s) (10:80) [09:16:22:892]: Machine policy value 'DisableRollback' is 0
MSI (s) (10:80) [09:16:22:892]: Incrementing counter to disable shutdown. 
Counter after increment: 0
MSI (s) (10:80) [09:16:22:892]: Note: 1: 1402 2: 



HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2 
MSI (s) (10:80) [09:16:22:894]: Note: 1: 2265 2:  3: -2147287035 
MSI (s) (10:80) [09:16:22:894]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2 
MSI (s) (10:80) [09:16:22:894]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied.  Counter after decrement: -1
MSI (s) (10:80) [09:16:22:894]: Post-install cleanup: removing installer file 'C:\Windows\Installer\c8de6843.msi'
MSI (s) (10:80) [09:16:22:896]: Post-install cleanup: removing installer file 'C:\Windows\Installer\{2DE751D3-33F4-4C3E-BD12-63E7F7F0A3C9}\icon.ico'
MSI (s) (10:80) [09:16:22:896]: Post-install cleanup: removing installer folder 'C:\Windows\Installer\{2DE751D3-33F4-4C3E-BD12-63E7F7F0A3C9}\' (if empty)
MSI (s) (10:80) [09:16:22:896]: Note: 1: 2318 2:  
MSI (s) (10:80) [09:16:22:897]: Destroying RemoteAPI object.
MSI (s) (10:B4) [09:16:22:897]: Custom Action Manager thread ending.
MSI (c) (78:7C) [09:16:22:898]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied.  Counter after decrement: -1
MSI (c) (78:7C) [09:16:22:898]: MainEngineThread is returning 0
=== Verbose logging stopped: 2/15/2019  9:16:22 ===
Ben_G
  • 724
  • 1
  • 7
  • 21

2 Answers2

3

The Actual Solution (after debugging):

Run: C:\ProgramData\Package Cache{Product-GUID}\ProductSetup.exe /uninstall /quiet


Duplicate Installation: You probably have a duplicate installation. Unless you accidentally left the Add / Remove Programs applet open during uninstall in which case you should close and reopen it to verify that the entry is still present.

"Noise": You could also have an issue with too many packages present to see that your setup.exe has installed as two separate MSI files. To prevent this, test on a clean virtual and check the Add / Remove Programs list well for other, related entries.

Product Code: You can find the product codes and product names for all products installed by using one of the methods described here: How can I find the product GUID of an installed MSI setup? Maybe try the PowerShell one-liner, or the VBScript.

Rollback: Note that an MSI can rollback its uninstall if a custom action fails during uninstall. This means that the rollback becomes a re-install or at least a recovery of the files that the uninstall removed. So in this scenario it looks like the uninstall ran, but the product was recovered due to a failing custom action. So the uninstall never "committed".

Uninstall: And here are several ways to uninstall MSI packages: Uninstalling an MSI file from the command line without using msiexec. When you have uninstalled all entries I would expect the ARP entry to be gone. Is this your own package? Duplicate installations are very common in such cases as a by-product of rapid test cycles.


Packed GUIDs: The GUIDs you find in the registry are generally packed, or in other words not formatted the same way as in your MSI.

Sample GUID Conversion:

HKEY_CLASSES_ROOT\Installer\Products

Packed GUID: 0076C0A639AEC2738817CDFC311D064A
Normal GUID: {6A0C6700-EA93-372C-8871-DCCF13D160A4}

Here are more details:

The latter link has a VBScript to convert Packed GUIDs to normal GUIDs.


LocalPackage: There is a local package cached on all systems when an MSI is installed. It will be located in %SystemRoot%\Installer. You can use this to locate the file, and you can then right click it in Windows Explorer and select "Uninstall".

The idea here is not to use this as your main approach, but to determine if there is a hidden MSI that you also need to uninstall to get rid of everything from ARP.

Here is a VBScript to show the LocalPackage path (create VB script file on desktop, save and double click. Look for output msiinfo.csv - double click and import to Excel or equivalent - or notepad):

' Retrieve all ProductCodes (with ProductName and ProductVersion)
Set fso = CreateObject("Scripting.FileSystemObject")
Set output = fso.CreateTextFile("msiinfo.csv", True, True)
Set installer = CreateObject("WindowsInstaller.Installer")

output.writeline ("Product Code,Product Name,Product Version,Local Package")

On Error Resume Next ' we ignore all errors

For Each product In installer.ProductsEx("", "", 7)
   productcode = product.ProductCode
   name = product.InstallProperty("ProductName")
   version=product.InstallProperty("VersionString")

   local=product.InstallProperty("LocalPackage")

   output.writeline (productcode & ", " & name & ", " & version & ", " & local)
Next

output.Close

Similar Answers:

Stein Åsmul
  • 34,628
  • 23
  • 78
  • 140
  • Thanks, but that's not really working. I ran the PowerShell utility described in the article and it shows the same GUID as I see in Orca as the product code, but that's different than the GUID that shows up under HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall which is why it still shows up in control panel. When I delete that registry entry it goes away from CP. – Ben_G Feb 14 '19 at 21:52
  • You must never delete anything from these keys. These keys are the internals of the MSI database and it is very easily corrupted. What you could have done would be to run a VBScript that would show you the path to the locally cached MSI in the ``%SystemRoot%\Installer`` folder, then you could have seen more details. Let us see if it is still there, I will add a VBScript to the answer. – Stein Åsmul Feb 14 '19 at 23:03
  • Thanks for the script. After uninstalling from the command line the GUID doesn't appear in the list but it is still in three places in the registry (and in the control panel): HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\, HKLM\SOFTWARE\Classes\Installer\Dependencies and HKCR\Installer\Dependencies. So my plan is to programatically delete those three entries after uninstalling. (Actually there are 6 entries - 3 with the original GUID and 3 with some other GUID that I have no idea where it comes from. – Ben_G Feb 15 '19 at 00:05
  • You must NOT poke around in the registry like that in the MSI database keys. You are likely to corrupt something for real, trip protection mechanisms in Windows or in Malware protection software or similar. Are you intending to do this on many PCs since you say programmatically? – Stein Åsmul Feb 15 '19 at 00:19
  • Yes - many PCs. All of our customers. What other choice do I have? The installer needs to uninstall prior versions before installing a new version and if I can't do that programmatically then the old version will still appear in the control panel which isn't acceptable.I can leave everything but the entry under HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ since that's what appears to be the trigger for it appearing in the control panel. – Ben_G Feb 15 '19 at 00:52
  • It is late, I am probably overlooking something obvious. I would guess that you are installing two MSIs - are you launching a ``setup.exe`` bundle? Can you test on a clean virtual? Then you will easily see what is added to the Add/Remove Applet after installation? Less crowded. The name of the other MSI could be unknown to you? – Stein Åsmul Feb 15 '19 at 00:56
  • There's a possibility that the installer is broken and important actions aren't performed during uninstallations. It could help to make uninstall with a logging enabled and look the log file. – montonero Feb 15 '19 at 07:44
  • [**Some logging hints here**](https://stackoverflow.com/a/49028367/129130). Are there custom actions after InstallFinalize? – Stein Åsmul Feb 15 '19 at 07:54
  • Stein - no custom actions after InstallFinalize. I'll look into logging. – Ben_G Feb 15 '19 at 16:57
  • Stein - I logged the uninstall and it all looks good (see above - I added it to the original post): It seems to have completed successfully and yet it still appears in Control Panel: – Ben_G Feb 15 '19 at 17:26
  • I just ditched my code and tried to do the upgrade via built-in InstallShield functionality, so I tried out-of-the-box and it says that I have a newer version installed. (The new version is 3.0 and 1.2 is installed so I don't know why it says that). Then I want back and deleted the PreventDowngrade upgrade item and now the new version installs and the old version is uninstalled, but the old version still appears in Control Panel. Ugh! Here's the log: https://www.dropbox.com/s/ey09jly4ud21eb2/install-upgrade.log?dl=0 – Ben_G Feb 15 '19 at 18:57
  • According this this article modifying that part of the registry is fine (although the article applies to windows 2000): https://support.microsoft.com/en-us/help/247501/how-to-manually-remove-programs-from-the-add-remove-programs-list – Ben_G Feb 15 '19 at 20:22
  • Added a couple of more sections. I will have a look at that log when I get a chance. It sort of seems like you have several MSI files installing and you only uninstall one of them, or your uninstall rolls back putting the install back in place and not completing at all. – Stein Åsmul Feb 17 '19 at 13:50
  • The log file reports "**User canceled action.**" ("SetupCompleteSuccess. [Return value 2](https://docs.microsoft.com/en-us/windows/desktop/msi/logging-of-action-return-values)."). That seems strange. Did you cancel something during the setup (a sub-setup)? Do you have custom actions towards the end of the GUI-sequence? Do you have any sub-installs or prerequisites? – Stein Åsmul Feb 17 '19 at 21:26
  • I've pretty much given up and I'm resigned to modifying the log. When I look in the log I only see one Value 2 and it's next to SetupComleteSuccess. I just searched for User canceled action and that's not in the log either. Not even "cancel" is found. No - no custom actions near the end. I'll look through what you've added, but I don't expect to solve this. – Ben_G Feb 18 '19 at 23:53
  • This WiX MSI wouldn't happen to be converted from an Installshield setup would it? I see **`ISSetupFilesCleanup`** in the log? – Stein Åsmul Feb 19 '19 at 02:24
  • I believe that is a custom action. It might partially run seeing as you might have the right binary embedded in the binary table? This could explain why it fails some operations, but not all. – Stein Åsmul Feb 19 '19 at 02:33
  • The log I attached is from the InstallShield installer that I wrote to replace the WiX installer - that's why you see ISSetupFilesCleanup. (That confused me as well for a while until I realized what we were looking at). – Ben_G Feb 19 '19 at 17:54
  • Hey Stein. I just posted another related question - maybe you can take a look? https://stackoverflow.com/questions/54776631/why-would-a-wix-installation-create-two-entries-in-hklm-software-wow6432node-mic – Ben_G Feb 19 '19 at 23:44
  • This didn't really answer my question, but Stein's other post did (https://stackoverflow.com/questions/54776631/why-would-a-wix-installation-create-two-entries-in-hklm-software-wow6432node-mic/54777375#54777375). Thanks! – Ben_G Feb 20 '19 at 16:39
0

The solution was to run C:\ProgramData\Package Cache{Product-GUID}\ProductSetup.exe /uninstall /quiet. While stein didn't answer that directly above he did in another post so I'm "closing" this and giving him credit.

Ben_G
  • 724
  • 1
  • 7
  • 21