Windows 从MSI文件中查找GUID

Windows 从MSI文件中查找GUID,windows,windows-installer,guid,Windows,Windows Installer,Guid,如何在Windows中列出已安装程序的GUID?或者,如果我有MSI文件,是否更容易找到GUID 我正在使用Orca查看MSI文件,但不确定在哪里可以找到GUID 谢谢 如果软件使用基于MSI的安装,通常(尽管不是普遍)可以在卸载条目中找到GUID。它通常是键名,或者出现在卸载字符串和/或卸载路径值中。有时候生活很简单,有一种价值观 可以在以下位置找到卸载条目: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninst

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

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

谢谢

如果软件使用基于MSI的安装,通常(尽管不是普遍)可以在卸载条目中找到GUID。它通常是键名,或者出现在卸载字符串和/或卸载路径值中。有时候生活很简单,有一种价值观

可以在以下位置找到卸载条目:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
在64位版本的Windows上,有两个这样的键,一个用于64位软件,另一个用于32位软件:

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

Windows Installer数据库的三个主要GUID是、和。第一个存储在摘要信息流(Orca中的视图菜单)中,其他存储在属性表中。(其他形式的数据库(如合并模块和修补程序)在相似的位置具有相似的GUID,如合并模块的GUID或修补程序代码GUID-每个GUID的存储方式与包代码相同。)


要在计算机上找到它们,可以查看卸载密钥,其中经常使用ProductCode。或者更好的方法是,如果您希望枚举计算机上当前安装的内容,可以调用。

有几种方法查找已安装软件包的产品GUID。请选择3号选项

最常见的是:

  • 使用regedit.exe在注册表中检查以下基本路径下方的。搜索应用程序名称(或者浏览每个子文件夹,直到找到为止)。找到后,可以将其传递给msiexec.exe:
  • -32位节:
    HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
    HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall(每个用户部分)
    
    -64位节:
    HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
    
    -合并部分(假设上述所有内容都合并在一起,我尚未验证):
    HKCR\安装程序\产品
    
  • %SystemRoot%\Installer中检查本地缓存的MSI包。这是最初用于在计算机上安装产品的原始MSI的缓存版本。
    • 您需要一个能够打开MSI文件的工具。以下是功能的列表和比较:
    • MSI是一个伪装的MS SQL数据库,您还应该能够使用任何兼容的MS SQL data viewer工具打开它
    • 此简单数据检索任务的首选工具是来自的免费MSI工具。它快速、小巧、可靠
    • 然后按照Michael Uhrman在上述答案中的建议,在摘要流中查找包代码,在属性表中查找升级和产品代码。在Windows资源管理器中,也可以从MSI文件的属性页中看到包代码
  • 使用Powershell列出软件包信息。我觉得这是最简单、最实用的选择。有关屏幕截图和示例,请参见此答案:
  • 如果您试图卸载有问题的产品,请参阅此综合卸载MSI回答:


    如果您觉得使用VBScript而不是Powershell更合适,请尝试Phil Wilson的回答:

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

    如果您只想知道给定MSI包含的ProductName和ProductCode(ProductId)是什么,而无需安装该MSI并检查注册表,您可以使用类似以下功能(灵感来自于):

    函数获取MSI属性{
    param(
    [参数(必需=$true)]
    [ValidateNotNullOrEmpty()]
    [System.IO.FileInfo]$path,
    [string[]$properties=@('ProductCode','ProductVersion','ProductName','Manufacturer','ProductLanguage')
    )
    开始{
    $windowsInstaller=(新对象-ComObject windowsInstaller.Installer)
    }
    过程{
    $table=@{}
    $msi=$windowsInstaller.GetType().InvokeMember('OpenDatabase','InvokeMethod',$null,$windowsInstaller,@($Path.FullName,0))
    foreach($properties中的$properties){
    试一试{
    $view=$msi.GetType().InvokeMember('OpenView','InvokeMethod',$null,$msi,(“从属性中选择值,其中属性='$($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))
    }
    抓住{
    $table.add($property,$null)
    }
    }
    $msi.GetType().InvokeMember('Commit','InvokeMethod',$null,$msi,$null)
    $view.GetType().InvokeMember('Close','InvokeMethod',$null,$view,$null)
    $msi=$null
    $view=$null
    返回$table
    }
    结束{
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($windowsInstaller)| Out Null
    [System.GC]::Collect()
    }
    }
    
    您需要更具体一些。你在找哪个GUID?一个典型的产品将有许多用于各种用途的GUID。下面添加了一个新的答案,列出了从任何系统检索此GUID的一些最简单的选项。将“UpgradeCode”添加到$properties中对于。。。但是找不到包代码的属性!?此GUID在我的情况下不是正确的产品,尽管它是