windows 从 MSI 文件中查找 GUID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11251034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 09:38:54  来源:igfitidea点击:

Find GUID From MSI File

windowswindows-installerguid

提问by dshipper

How can I list the GUID of an installed program in Windows? Alternatively, is it easier to find the GUID if I have the MSI file?

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

I'm looking through the MSI file with Orca but not sure where to look to find the GUID.

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

Thanks!

谢谢!

回答by Michael Urman

The three main GUIDs of a Windows Installer database are the Package Code, ProductCode, and UpgradeCode. The first is stored in the summary information stream (View menu in Orca), and the others are stored in the Property table. (Other forms of databases such as merge modules and patches have similar GUIDs in similar places, such as the merge module's GUID or the patch code GUID - each stored identically to the package code.)

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

To find them on a machine, you can look in the Uninstall key, where the ProductCode is often used. Or better yet, if you are looking to enumerate what is currently installed on the machine, you can call MsiEnumProducts.

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

回答by Stein ?smul

There are several ways to locate the product GUIDfor installed packages. Please prefer option number 3.

有几种方法可以查找产品GUID进行安装的软件包。请选择第 3 个选项

The most common are:

最常见的是:

  1. Check in the registryunderneath the following base paths using regedit.exe. Search for the application name (or just browse through each sub folder untill you find it). When you have found it you can pass it to msiexec.exe:
  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. Check the locally cached MSI packagein %SystemRoot%\Installer. This is a cached version of the original MSI that was originally used to install the product on your computer.
    • You will need a tool capable of opening MSI files. Here is a list and comparison of features: What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc.
    • An MSI is an MS SQL database in disguise, you should also be able to open it with any compatible MS SQL data viewer tool.
    • The free MSI tool "Orca"from the Windows SDKis the preferred one for this simple data retrieval task. It is quick, small and reliable.
    • Then follow Michael Uhrman's advice from his answer above, and locate the package code in the summary stream, and the upgrade and the product code in the Property table. The package code is also visible from an MSI file's property page in Windows Explorer.
  2. Use Powershellto list package information. I find this the easiest and most practical option. See this answer for a screenshot and a sample: How can I find the product GUID of an installed MSI setup?
  1. 检查本地缓存的MSI软件包的%SystemRoot%\ Installer程序。这是最初用于在您的计算机上安装产品的原始 MSI 的缓存版本。
    • 您将需要一个能够打开 MSI 文件的工具。以下是功能列表和比较: 使用什么安装产品?InstallShield、WiX、Wise、Advanced Installer 等
    • MSI 是伪装的 MS SQL 数据库,您还应该能够使用任何兼容的 MS SQL 数据查看器工具打开它。
    • 来自Windows SDK的免费 MSI 工具Orca是完成这项简单数据检索任务的首选工具。它快速、小巧且可靠。
    • 然后按照 Michael Uhrman 上面的回答中的建议,在摘要流中找到包代码,在属性表中找到升级和产品代码。也可以从 Windows 资源管理器中的 MSI 文件的属性页看到包代码。
  2. 使用Powershell列出包信息。我发现这是最简单和最实用的选择。请参阅此答案以获取屏幕截图和示例:如何找到已安装的 MSI 设置的产品 G​​UID?

If what you are trying to do is to uninstall the product in question, see this comprehesive uninstall MSI answer: Uninstalling an MSI file from the command line without using msiexec

如果您尝试做的是卸载有问题的产品,请参阅此综合卸载 MSI 答案:在不使用 msiexec 的情况下从命令行卸载 MSI 文件

If you feel more comfortable using VBScriptinstead of Powershell, please try this answer from Phil Wilson: how to find out which products are installed - newer product are already installed MSI windows

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

回答by grenade

if you just want to know what ProductName and ProductCode (ProductId) a given MSI contains, without installing that MSI and checking the registry, you can query the MSI itself with PowerShell using a function like this (inspired by http://www.scconfigmgr.com/2014/08/22/how-to-get-msi-file-information-with-powershell):

如果您只想知道给定 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()
  }
}

回答by Farkhod

My solution is that I wrote a small console app which returns ProductCode of any MSI file (name is passed as program argument). I'm doing it by reading the guid from .msi file itself. Basically I'm opening that msi file as a string and looking for a text started with "ProductCode", getting its index and taking 38-chars before that index position. Here is the screenshot: screenshot

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

回答by Harry Johnston

Typically (though not universally) if a piece of software uses MSI-based installation the GUID can be found in the Uninstall entry. It will usually either be the key name or will appear in the UninstallString and/or UninstallPath value. Sometimes life is easy and there is a ProductGuid value.

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

Uninstall entries can be found here:

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

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

On a 64-bit version of Windows there are two such keys, one for 64-bit software and a second for 32-bit software:

在 64 位版本的 Windows 上有两个这样的键,一个用于 64 位软件,第二个用于 32 位软件:

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall