Is there an alternative to GUID when using msiexec to uninstall an application?

浪尽此生 提交于 2019-12-28 06:54:32

问题


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 use reg 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!