如何找到已安装的MSI设置的产品GUID?


Answers:


163

对于升级代码检索: 如何找到已安装的MSI文件的升级代码?


简洁版本

下面的信息随着时间的推移已经有了很大的增长,并且可能变得太复杂了。如何快速获取产品代码?(四种方法):

1- Use the Powershell "one-liner"

向下滚动以获取屏幕截图和分步操作。以下免责声明-轻微或中等风险,具体取决于您要求的人。为我工作正常。通常,可以取消此选项触发的任何自修复。触发的程序包完整性检查确实会添加一些事件日志“噪音”。注意IdentifyingNumber ProductCode(WMI特点)。

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

快速启动Powershell:按住Windows key,点击R,键入“ powershell”,然后按Enter

2- Use VBScriptgithub.com上的脚本

在下面的“替代工具”(第3节)中介绍。由于下面将详细说明的原因,此选项可能比Powershell更安全。它在本质上是(多)触发MSI自我修复,因为它没有经过WMI的和不能够(它访问MSI COM API直接-在起泡速度)。但是,它比Powershell选项(几行代码)涉及更多的内容

3- Registry Lookup

有些人发誓要在注册表中查找内容。不是我推荐的方法-我喜欢使用正确的API(或者说:OS函数调用)。总是存在仅由API实现内部解释的奇怪异常:

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
  • HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall

4- Original MSI File / WiX Source

您可以Product CodeProperty table任何MSI文件(以及其他任何属性)中找到。但是,可以想象,GUID(很少)会在安装时被应用的转换覆盖,因此与注册该产品的GUID不匹配(上述方法1和2将报告实际的产品代码-已在Windows中注册)。罕见的情况)。

您需要一个工具来查看MSI文件。请参阅以下答案的底部,以获取可以下载的免费工具的列表(或参见下面的快速选项):如何比较两个(或多个)MSI文件的内容?

更新:为了方便和需要速度:-),请从此直接下载的热链接下载SuperOrca,不要拖延和大惊小怪-该工具足以完成工作-安装,打开MSI并直接转到“属性”表并找到行(请始终对病毒进行检查,直接检查直接下载的热链接-显然-您可以使用virustotal.com这样做-利用数十种防病毒和恶意软件套件进行的在线扫描来扫描您上传的内容)。ProductCode

Orca是Microsoft自己的工具,它随Visual StudioWindows SDK一起安装。尝试在Orca-x86_en-us.msi下面搜索- Program Files (x86)并安装MSI(如果找到)。

  • 当前路径C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86
  • 适当更改版本号

在下面,您将找到原始答案,它“有机地增长”了很多细节。

如果这是您需要执行的任务,请参见下面的“卸载MSI软件包”部分。


检索产品代码

更新:如果您还需要升级代码,请检查以下答案: 如何找到已安装的MSI文件的升级代码?(在表输出中检索相关的产品代码,升级代码和产品名称-与下面的类似)。

  • 无法使用PowerShell?请参阅下面的“替代工具”部分。
  • 想要卸载?请参阅下面的“卸载MSI软件包”部分。

启动Powershell按住Windows键,点按R,释放Windows键,键入“ powershell”,然后按OK),然后运行以下命令以获取已安装的MSI软件包产品代码列表以及本地缓存软件包路径和该产品名称(最大化PowerShell窗口,以避免截断名称)。

在运行此命令行之前,请阅读下面的免责声明(没有危险,只是一些潜在的麻烦)。“替代工具”下的第3节演示了使用VBScript获得相同信息的另一种非WMI方法。如果您尝试卸载软件包,则下面有一些示例msiexec.exe命令行的部分:

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

输出应该类似于此:

在此处输入图片说明

注意!由于某些奇怪的原因,“ ProductCode 在WMI中被称为“ IdentifyingNumber”。换句话说,在上面的图片中,IdentifyingNumberProductCode。

如果您需要对许多远程计算机远程运行此查询,请参阅下面的“从远程计算机检索产品代码”部分。

免责声明(重要说明,请在运行命令之前阅读!):由于Microsoft的设计怪异,对WMI的任何调用Win32_Product (如下面的PowerShell命令)都将触发对包Estate的验证。除了速度很慢之外,在极少数情况下,这可能会触发MSI自修复。这可以是小包装,也可以是大包装,例如Visual Studio。在大多数情况下,这不会发生-但存在风险。不要在重要会议之前立即运行此命令-它永远不会很危险(它是只读的),但是在极少数情况下可能会导致长时间的修复(我认为您也可以取消自我修复-除非被相关软件包积极阻止,但是如果再次调用Win32_Product,它将重新启动,并且将一直持续到您让自我修复完成为止-有时即使您一定要完成:如何确定导致Windows Installer重复进行自我修复的原因?)。

仅作记录:有些人报告了他们的事件日志,其中充满了MsiInstaller EventID 1035条目(请参阅代码负责人的答案)-显然是由WMI查询Win32_Product类引起的(个人而言,我从未见过)。这与上面建议的Powershell命令没有直接关系,它是在WIM类Win32_Product的常规使用中。

您还可以列表形式(而不是表格)获取输出:

get-wmiobject -class Win32_Product

在这种情况下,输出类似于以下内容:

在此处输入图片说明


从远程计算机检索产品代码

从理论上讲,您应该只可以在命令本身中指定一个远程计算机名称。这是与在机器“ RemoteMachine”(-ComputerName RemoteMachine添加的部分)上运行的上述命令相同的命令:

get-wmiobject Win32_Product -ComputerName RemoteMachine | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

如果您以适当的域上的域管理员权限运行,这可能会起作用。在工作组环境(小型办公室/家庭网络)中,您可能必须直接将用户凭据添加到WMI调用中以使其起作用。

此外,WMI中的远程连接受到(至少)Windows防火墙DCOM设置用户帐户控制(UAC)(以及任何其他非Microsoft因素的影响),例如,真实防火墙第三方软件防火墙各种安全软件种类等)。它是否可以工作取决于您的确切设置。

更新:有关远程WMI运行的详细内容,可以在以下答案中找到如何找到已安装的MSI文件的升级代码?。看来是防火墙规则,并且通过注册表调整抑制UAC提示可以使事情在工作组网络环境中正常工作。不建议在安全方面进行更改,但是它对我有用。


替代工具

PowerShell需要安装.NET框架(当前似乎在3.5.1版中?2017年10月)。即使安装了.NET ,实际的PowerShell应用程序本身也可能会从计算机中丢失。最后,我相信PowerShell可以被各种系统策略和特权禁用或锁定

在这种情况下,您可以尝试其他几种方法来检索产品代码。我首选的替代方法是VBScript,它既快速又灵活(但也可以锁定在某些计算机上,脚本编写总是比使用工具要复杂得多)。

  1. 让我们先从一个内置的Windows WMI工具wbemtest.exe
  • 启动wbemtest.exe按住Windows键,点击R,释放Windows键,输入“ wbemtest.exe”,然后按OK)。
  • 单击连接,然后单击确定(名称空间默认为root \ cimv2),然后再次单击“连接”。
  • 单击“查询”并键入此WQL命令(SQL风格):SELECT IdentifyingNumber,Name,Version FROM Win32_Product然后单击“使用”(或等效按钮-该工具将被本地化)。
  • 示例输出屏幕截图(已截断)。不是最好的格式,但是您可以获得所需的数据。IdentifyingNumber是MSI产品代码

wbemtest.exe

  1. 接下来,您可以尝试使用更全面的自定义WMI工具,例如 WMIExplorer.exe
  • Windows中不包括此功能。但是,这是一个非常好的工具。推荐的。
  • 在以下位置查看:https : //github.com/vinaypamnani/wmie2/releases
  • 启动该工具,单击“连接”,双击“ ROOT \ CIMV2”
  • 在“查询选项卡”中,键入以下查询SELECT IdentifyingNumber,Name,Version FROM Win32_Product,然后按执行。
  • 跳过了屏幕截图,该应用程序需要过多的屏幕空间。
  1. 最后,您可以尝试使用VBScript通过MSI自动化界面(Windows的核心功能-与WMI无关)来访问信息。
  • 复制以下脚本并将其粘贴到桌面上的* .vbs文件中,然后尝试通过双击运行它。您的桌面必须对您可写,或者您可以使用任何其他可写位置。
  • 这不是一个很棒的VBScript。简洁性优于错误处理和完整性,但是它应该以最小的复杂度完成任务。
  • 将在运行脚本的文件夹中创建输出文件(该文件夹必须是可写的)。输出文件称为msiinfo.csv
  • 双击文件以在电子表格应用程序中打开,在导入时选择逗号作为分隔符-或-只需在记事本或任何文本查看器中打开文件即可。
  • 在电子表格中打开将允许使用高级排序功能。
  • 可以轻松地修改此脚本,以显示有关MSI安装的大量更多详细信息。可以在此处找到此示例:如何找出已安装的产品-已安装较新的产品的MSI windows
' Retrieve all ProductCodes (with ProductName and ProductVersion)
Set fso = CreateObject("Scripting.FileSystemObject")
Set output = fso.CreateTextFile("msiinfo.csv", True, True)
Set installer = CreateObject("WindowsInstaller.Installer")

On Error Resume Next ' we ignore all errors

For Each product In installer.ProductsEx("", "", 7)
   productcode = product.ProductCode
   name = product.InstallProperty("ProductName")
   version=product.InstallProperty("VersionString")
   output.writeline (productcode & ", " & name & ", " & version)
Next

output.Close

目前,我无法想到任何其他用于检索产品代码的通用选项,请添加。只需内联编辑,而不要添加太多注释。

您当然可以通过调用MSI自动化接口(基于COM)或C ++ MSI安装程序函数(Win32 API)从应用程序内部访问此信息。甚至使用WMI查询从您的应用程序中像你这样的样品中做上述使用PowerShellwbemtest.exeWMIExplorer.exe


卸载MSI软件包

如果您要卸载要为其找到产品代码的MSI软件包,则可以使用提升的命令提示符(搜索cmd.exe,右键单击并以admin身份运行),如下进行操作:

选项1基本的交互式卸载,无需登录(快速简便):

msiexec.exe /x {00000000-0000-0000-0000-00000000000C}

快速参数说明:

/X = run uninstall sequence
{00000000-0000-0000-0000-00000000000C} = product code for product to uninstall

如果愿意,您还可以启用(详细)日志记录并以静默方式运行,使我们进入选项2:

选项2通过详细日志记录进行静默卸载(对于批处理文件而言更好):

msiexec.exe /x {00000000-0000-0000-0000-00000000000C} /QN /L*V "C:\My.log" REBOOT=ReallySuppress

快速参数说明:

/X = run uninstall sequence
{00000000-0000-0000-0000-00000000000C} = product code for product to uninstall
/QN = run completely silently
/L*V "C:\My.log"= verbose logging at specified path
REBOOT=ReallySuppress = avoid unexpected, sudden reboot

此处提供了有关MSI卸载(用于卸载MSI软件包的多种不同方式)的综合参考从命令行卸载MSI文件,而无需使用msiexec。有许多不同的卸载方式。

如果要编写批处理文件,请查看上面第3节的链接答案,以了解一些常见和标准的卸载命令行变体。

以及指向msiexec.exe的快速链接(命令行选项)(来自MSDN的msiexec.exe命令行概述)。还有Technet版本


检索其他MSI属性/信息(f.ex升级代码)

更新:请找到有关如何找到已安装软件包的升级代码的新答案,而不是手动在MSI文件中查找代码。对于已安装的软件包,这要可靠得多。如果未安装该软件包,则仍需要查看MSI文件(或用于编译MSI的源文件)以查找升级代码。留在下面的较旧部分中:

如果要获取UpgradeCode其他MSI属性,则可以从上图所示的“ LocalPackage ”指定的位置打开产品的缓存安装MSI (类似:C:\WINDOWS\Installer\50c080ae.msi-这是一个十六进制文件名,每个文件名都是唯一的)系统)。然后,在“属性表”中查找UpgradeCode(可以在转换中重新定义UpgradeCode-确保获得正确的值,您需要以编程方式从系统中检索代码-我将提供脚本但是,在缓存的MSI中找到的UpgradeCode通常是正确的)。

要打开缓存的MSI文件,请使用Orca或其他打包工具。这里讨论了不同的工具(它们都可以使用):使用哪种安装产品?InstallShield,WiX,Wise,Advanced Installer等。如果您没有安装这样的工具,那么您最好的选择是尝试Super Orca(它很容易使用,但未经我广泛测试)。

更新:这是一个新的答案,其中包含可用于查看MSI文件的各种免费产品的信息:如何比较两个(或多个)MSI文件的内容?

如果已安装Visual Studio,请尝试在“ Orca-x86_en-us.msi-”下进行搜索Program Files (x86)并安装(这是Microsoft自己的官方MSI查看器和编辑器)。然后在开始菜单中找到Orca。赶紧去时间:-)。从技术上讲,Orca是作为Windows SDK(不是Visual Studio)的一部分安装的,但是Windows SDK是与Visual Studio安装捆绑在一起的。如果您没有安装Visual Studio,也许您认识谁?只需让他们搜索此MSI并将其发送给您(这是一个很小的mb文件)-应该花费他们几秒钟。更新:您需要几个CAB文件以及MSI-这些文件在找到MSI的同一文件夹中找到。如果没有,您可以随时下载Windows SDK(它是免费的,但它很大-并且您安装的所有内容都会降低PC的速度)。我不确定SDK的哪一部分安装了Orca MSI。如果您这样做,请在此处编辑并添加详细信息。



相似的主题(仅供参考和方便访问-我应该清理此列表):


谢谢。我尝试使用geek.exe和Revo,但在注册表中输入了一个关键字,但没有记录guid,这会使我看到空白。
保罗·托茨克

2
Win32_Product不应查询,因为它不是只读操作。显然,它会对每个软件包进行一致性检查,然后在发现任何安装的情况下进行修复安装。请参阅sdmsoftware.com/group-policy-blog/wmi/…support.microsoft.com/kb/974524
Michael Wild,

我相信以上答案(免责声明部分)中已对此进行了详尽记录。Win32_Product之所以调用,是因为UpgradeCode无法以其他方式轻松访问。这里描述了另一种方法,但是它也有一些令人不愉快的方面(MSI API会话对象)。
斯坦·奥斯穆尔(SteinÅsmul),

我以为您在谈论UpgradeCode。您可以通过MSI API轻松获得ProductCode,我为上述内容提供了VBScript(“替代工具”中的第3节)。也许可以创建Powershell cmdlet来完成这项工作。也许我有空的时候看看。它可以直接通过MSI API-在后台进行。
SteinÅsmul'18

1
我有一个更高级的VBScript,可以将输出格式化为可排序,可过滤/可搜索的HTML格式,但是我对它的质量检查还没有完成,它也主要供我自己使用和测试。它还显示升级代码和相关的产品代码(共享相同的升级代码)。我建议您在电子表格应用程序(例如Microsoft Excel)中打开导出的文本文件,然后将其导入以逗号分隔的定界列表中,然后就可以进行格式化。只需将输出文件重命名为msiinfo.csv并双击它-然后将逗号设置为定界符即可。
SteinÅsmul'18

2

如果安装程序太多,无法轻松找到所需的内容,则可以使用一些Powershell提供过滤器,并按显示名称将其缩小一些。

$filter = "*core*sdk*"; (Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall).Name | % { $path = "Registry::$_"; Get-ItemProperty $path } | Where-Object { $_.DisplayName -like $filter } | Select-Object -Property DisplayName, PsChildName

至于以前的答案,Get-WmiObject在PS 7中不可用。此代码可完美运行。谢谢!
Goujon

0

还有一个非常有用的GUI工具,称为产品浏览器,它似乎是由Microsoft或至少是Microsoft的员工制造的。

可以在Github上找到产品浏览器

我个人非常轻松地找到了所需的GUID。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.