简体   繁体   中英

Uninstalling msi via msiexec fails with a 'only valid for applications installed' message

We have a legacy software installation that we're trying to remove from our organisation. We have different versions and are trying to create a universal uninstaller for all versions. We've come across a particular release that doesn't seem to be able to be uninstalled via command line though. And it's proving difficult to create a workaround.

I've found the GUID of the application in the registry via

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

And the command I run is:

msiexec /x {080FDF44-6D15-4D2E-977E-74D5168198E7}

I get an application prompt asking me if I want to uninstall the product, so I click 'Yes'. And then it looks like it's starting but never actually does anything. So I dug round the registry and found another GUID in:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Userdata\S-1-5-18\Products\44FDF08051D6E2D479E7475D6118897E

If I run the same command as above with the different GUID, I get the application confirmation box asking for uninstall then after clicking OK, I get an error saying:

The installation package could not be opened. Verify the package exists and you can access it.......

I've been into C:\\Windows\\Installer into the folder with the above GUID and all that is in there is an icon and an *.mst file. In the root of C:\\Windows\\Installer, there is an *.msi called the same product in the details but with another version ID of:

8A2C4F93-4B31-4474-B9F2-2E51BF5D71A8

If I run the msiexec against that ID then I get a confirmation box again then another error which says

The action is only valid for products that are currently installed.

If I run the uninstaller, it uninstalls fine from the programs and features and uses the generated *.msi for the uninstalled (eg C:\\Windows\\Installer\\241a6.msi and matches the product ID of 8A2C4F93-4B31-4474-B9F2-2E51BF5D71A8). This will change form machine to machine. Any other ideas on how to get this off in a neat and managed way?

You can't dredge the registry for ProductCode guids because they are obfuscated. If you don't really know the ProductCode, then look at ways of enumerating installed products. For example, the direct C++ way is MsiEnumerateProducts, and C# pinvoke equivalents, something like this:

MSI Interop using MSIEnumRelatedProducts and MSIGetProductInfo

Then you will get the actual ProductCode and can get other info with it.

If sometimes it doesn't work when you are absolutely sure of the ProductCode, then it was perhaps installed in a per user context that's different from the one you're running the program with.

Also, for MSI-installed products Windows doesn't use the uninstall string, it just uses the ProductCode directly. Again, registry dredging is not the right thing when there are actual APIs specifically to enumerate installed MSI products.

If an uninstall requires access to the original MSI that it was installed from, then there are at least two reasons:

  1. The MSI has an unconditional ResolveSource action that forces it to ask for the oroginal MSI file.

  2. The cached version of the MSI file has been removed from C:\\windows\\installer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM