从MSI文件中查找GUID

时间:2012-06-28 18:48:30

标签: windows windows-installer guid

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

我正在浏览Orca的MSI文件,但不确定在哪里查找GUID。

谢谢!

5 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:6)

找到已安装软件包的产品GUID 有多种方法。请首选3号选项

最常见的是:

  1. 使用regedit.exe检入以下基本路径下的注册表。搜索应用程序名称(或只浏览每个子文件夹,直到找到它)。找到它后,您可以将其传递给msiexec.exe:
  2. - 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文件的工具。以下是功能列表和比较:What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc
      • MSI是伪装的MS SQL数据库,您还应该能够使用任何兼容的MS SQL数据查看器工具打开它。
      • 来自Orca的免费MSI工具Windows SDK是此简单数据检索任务的首选工具。它快速,小巧,可靠。
      • 然后按照上面的答案跟随Michael Uhrman的建议,找到摘要流中的包代码,以及Property表中的升级和产品代码。从Windows资源管理器中的MSI文件属性页面也可以看到包代码。
    2. 使用 Powershell 列出包裹信息。我发现这是最简单,最实用的选择。有关屏幕截图和示例,请参阅此答案: How can I find the product GUID of an installed MSI setup?
    3. 如果您要执行的操作是卸载相关产品,请参阅此comprehesive卸载MSI答案: Uninstalling an MSI file from the command line without using msiexec

      如果您觉得使用 VBScript 而不是Powershell感觉更舒服,请尝试Phil Wilson的回答:how to find out which products are installed - newer product are already installed MSI windows

答案 2 :(得分:2)

如果您只想知道给定MSI包含什么ProductName和ProductCode(ProductId),而无需安装该MSI并检查注册表,则可以使用PowerShell这样的功能(由{{3 }):

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()
  }
}

答案 3 :(得分: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

答案 4 :(得分:1)

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