Is there an alternative to GUID when using msiexec to uninstall an application?
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?
Solution 1:
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.
Solution 2:
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.