13

如何在 Windows 中列出已安装程序的 GUID?或者,如果我有 MSI 文件,是否更容易找到 GUID?

我正在使用 Orca 浏览 MSI 文件,但不确定在哪里可以找到 GUID。

谢谢!

4

5 回答 5

15

Windows Installer 数据库的三个主要 GUID 是Package CodeProductCodeUpgradeCode。第一个存储在摘要信息流中(Orca 中的查看菜单),其他存储在属性表中。(其他形式的数据库,例如合并模块和补丁,在类似的地方有类似的 GUID,例如合并模块的 GUID 或补丁代码 GUID——每个都与包代码存储相同。)

要在机器上找到它们,您可以查看经常使用 ProductCode 的 Uninstall 键。或者更好的是,如果您希望枚举机器上当前安装的内容,您可以调用MsiEnumProducts

于 2012-06-29T12:02:59.303 回答
7

有几种方法可以找到已安装软件包的产品G ​​UID。请选择第 3 个选项

最常见的是:

  1. 使用 regedit.exe 在以下基本路径下检查注册表。搜索应用程序名称(或浏览每个子文件夹直到找到它)。找到它后,您可以将其传递给 msiexec.exe:
- 32-BIT SECTION:

 HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
 HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall (per user section)
- 64-BIT SECTION:

 HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
- MERGED SECTION (supposedly all of the above merged together, I have not verified):

 HKCR\Installer\Products
  1. 检查%SystemRoot%\Installer中本地缓存的 MSI 包。这是最初用于在您的计算机上安装产品的原始 MSI 的缓存版本。
    • 您将需要一个能够打开 MSI 文件的工具。以下是功能列表和比较:使用什么安装产品?InstallShield、WiX、Wise、高级安装程序等
    • MSI 是伪装的 MS SQL 数据库,您还应该能够使用任何兼容的 MS SQL 数据查看器工具打开它。
    • Windows SDK中的免费 MSI 工具Orca是这个简单数据检索任务的首选工具。它快速、小巧且可靠。
    • 然后按照 Michael Uhrman 上面的回答中的建议,在摘要流中找到包代码,在属性表中找到升级和产品代码。包代码也可以从 Windows 资源管理器中的 MSI 文件的属性页中看到。
  2. 使用Powershell列出包信息。我发现这是最简单和最实用的选择。请参阅此答案以获取屏幕截图和示例:如何找到已安装的 MSI 设置的产品 G​​UID?

如果您要卸载有问题的产品,请参阅此全面的卸载 MSI 答案:Uninstalling an MSI file from the command line without using msiexec

如果您觉得使用VBScript而不是 Powershell 更舒服,请尝试 Phil Wilson 的回答:如何找出已安装的产品 - 已安装较新的产品 MSI windows

于 2015-04-29T08:17:55.160 回答
6

如果您只想知道给定 MSI 包含的 ProductName 和 ProductCode (ProductId),而无需安装该 MSI 并检查注册表,您可以使用 PowerShell 使用类似这样的函数查询 MSI 本身(灵感来自http://www.scconfigmgr .com/2014/08/22/how-to-get-msi-file-information-with-powershell):

function Get-MSIProperties {
  param (
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [System.IO.FileInfo] $path,

    [string[]] $properties = @('ProductCode', 'ProductVersion', 'ProductName', 'Manufacturer', 'ProductLanguage')
  )
  begin {
    $windowsInstaller = (New-Object -ComObject WindowsInstaller.Installer)
  }
  process {
    $table = @{}
    $msi = $windowsInstaller.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $windowsInstaller, @($Path.FullName, 0))
    foreach ($property in $properties) {
      try {
        $view = $msi.GetType().InvokeMember('OpenView', 'InvokeMethod', $null, $msi, ("SELECT Value FROM Property WHERE Property = '$($property)'"))
        $view.GetType().InvokeMember('Execute', 'InvokeMethod', $null, $view, $null)
        $record = $view.GetType().InvokeMember('Fetch', 'InvokeMethod', $null, $view, $null)
        $table.add($property, $record.GetType().InvokeMember('StringData', 'GetProperty', $null, $record, 1))
      }
      catch {
        $table.add($property, $null)
      }
    }
    $msi.GetType().InvokeMember('Commit', 'InvokeMethod', $null, $msi, $null)
    $view.GetType().InvokeMember('Close', 'InvokeMethod', $null, $view, $null)
    $msi = $null
    $view = $null
    return $table
  }
  end {
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($windowsInstaller) | Out-Null
    [System.GC]::Collect()
  }
}
于 2018-08-28T08:39:31.487 回答
1

通常(尽管不普遍)如果一个软件使用基于 MSI 的安装,则 GUID 可以在卸载条目中找到。它通常是键名或出现在 UninstallString 和/或 UninstallPath 值中。有时生活很轻松,并且有一个 ProductGuid 值。

卸载条目可以在这里找到:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

在 64 位版本的 Windows 上,有两个这样的密钥,一个用于 64 位软件,另一个用于 32 位软件:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
于 2012-06-29T02:04:47.127 回答
1

我的解决方案是我编写了一个小型控制台应用程序,它返回任何 MSI 文件的 ProductCode(名称作为程序参数传递)。我通过从 .msi 文件本身读取 guid 来做到这一点。基本上,我将该 msi 文件作为字符串打开并查找以“ProductCode”开头的文本,获取其索引并在该索引位置之前取 38 个字符。这是屏幕截图:截屏

于 2017-10-17T05:57:26.447 回答