问题
We're currently using a GUID to identify the application when running our uninstall script which contains msiexec. The problem I'm having is the GUID changes every time I install the latest version of the application, so I was wondering if there is a different way that I can identify our application running using msiexec?
回答1:
The usual way that people get around the various ProductCode values in this situation is to start with the more constant UpgradeCode.
Given the UpgradeCode, you can use MsiEnumRelatedProducts (or script or MSI interop equivalent) to return the ProductCode. Code like this typically never needs to be changed.
I'm pretty sure PowerShell should be able to do this.
回答2:
First of all: it is normal that the product GUID changes for new versions of the application, though it is also possible to upgrade some applications without changing the product GUID (referred to as minor upgrades - as opposed to major upgrades that change the product GUID). What tends to remain stable between different releases of the same product is the UpgradeCode (it defines a family of related products). ProductCode uniquely identifies a product (in a specific version).
There are some options for uninstall listed here: Uninstalling an MSI file from the command line without using msiexec.
I suppose you could use the MSI file name as illustrated in section 3
, or if the product name remains stable you could use it along with automation to look up the correct product GUID to uninstall the product in question. I will test this in a moment and update the answer.
UPDATE: A sample VBScript to uninstall product by "product name" (assuming it remains constant across releases, which it normally does, but there is no guarantee - it depends on the product).
Find the product name in Add/Remove Programs - or use the tiny VBScript linked to at the bottom of this answer to export a little text file with info for all installed packages.
' On Error Resume Next ' Used to suppress errors
Const msiUILevelNone = 2
Const msiUILevelFull = 5
Const msiInstallStateAbsent = 2
Set installer = CreateObject("WindowsInstaller.Installer")
Set products = installer.ProductsEx("", "", 7)
installer.UILevel = msiUILevelFull ' Running with full GUI (if available in MSI)
' installer.UILevel = msiUILevelNone ' Will run uninstall silently, run script with admin rights
' Get the product name from the user
productname = InputBox("Please enter the product name for the MSI package you wish to uninstall:")
If productname = vbCancel Or Trim(productname) = "" Then
WScript.Quit(0)
End If
' Iterate over all MSI packages on the box
For Each product In products
currentproduct = product.InstallProperty("ProductName")
If LCase(currentproduct) = LCase(productname) Then
installer.ConfigureProduct product.productcode, 0, 2 ' msiInstallStateAbsent
MsgBox "Ran uninstall for: " & currentproduct
Exit For ' End product iteration, assuming only one product needed uninstall
End If
Next
Set installer = Nothing
MsgBox "Finished."
UPDATE: You can create yourself a quick list of product codes and product names using VBScript as described towards the bottom of this answer: How can I find the product GUID of an installed MSI setup? . This particular VBScript is as simple as it can possibly get I think.
回答3:
What do you know that doesn't change, or that does change but you can easily track?
Say the product code changes, but the upgrade code doesn't. You could follow PhilDW's suggestions to retrieve a product code from that upgrade code using MsiEnumRelatedProducts or Installer.Related or equivalent.
Say the name doesn't stays the same. You could follow Stein's suggestions to find the product code by product name, starting with MsiEnumProductsEx or Installer.ProductsEx or equivalent.
Say you cache a local copy of the installing .msi's in an unchanging location, or one easily found by your script. You could follow 4c74356b41's suggestion to use that path in a command line to msiexec. (Note that msiexec /x accepts either a package path or a product code.)
Say you don't like any of those options. Perhaps you can add a registry value in HKEY_LOCAL_MACHINE\Software\YourCompany\YourProduct, setting a string value ProductCode to
[ProductCode]
. Then you can usereg query HKLM\Software\YourCompany\YourProduct /v ProductCode
, or equivalent (sorry, I'm a dunce with PowerShell), to fetch the current product code. (At least if you account for 32-bit vs 64-bit paths, of course.)
来源:https://stackoverflow.com/questions/48669243/is-there-an-alternative-to-guid-when-using-msiexec-to-uninstall-an-application