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

问题描述 投票:55回答:1

我需要找到已安装的MSI文件的产品GUID,以便执行patchinguninstallhow-to uninstall)以及auditing purposes等维护。

powershell wix windows-installer install uninstall
1个回答
114
投票

对于升级代码检索:How can I find the Upgrade Code for an installed MSI file?


精简版

以下信息随着时间的推移而大大增加,可能会变得有点过于复杂。如何快速获得产品代码? (四种方法):

1. Use the Powershell "one-liner"

向下滚动屏幕截图并逐步显示。免责声明也低于 - 轻微或中等风险取决于您的要求。对我来说工作正常。通常应该可以取消由此选项触发的任何自我修复。触发的包完整性检查确实添加了一些事件日志“噪音”。注意! IdentifyingNumberProductCode(WMI的特点)。

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

快速启动Powershell:按住Windows键,点击R,输入“powershell”并按Enter键

2. Use VBScript

在“替代工具”(第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

您可以在任何MSI文件(以及任何其他属性)的Product Code中找到Property table。但是,GUID可以(很少)被安装时应用的转换覆盖,因此不符合产品注册的GUID(上面的方法1和2将报告真实的产品代码 - 在Windows中注册 - 在这样的罕见的场景)。

您需要一个工具来查看MSI文件。请参阅以下答案的底部,以获取可下载的免费工具列表(或参见下面的快速选项):How can I compare the content of two (or more) MSI files?

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

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


在下面你会发现原来的答案“有机地成长”到很多细节。

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


检索产品代码

更新:如果您还需要升级代码,请检查以下答案:How can I find the Upgrade Code for an installed MSI file?(在表输出中检索关联的产品代码,升级代码和产品名称 - 类似于下面的那个)。

  • 无法使用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”。换句话说 - 在上面的图片中,IdentifyingNumber是ProductCode。

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

免责声明(重要的是,请在运行命令之前阅读!):由于奇怪的Microsoft设计,任何对Win32_Product的WMI调用(如下面的PowerShell命令)都会触发包版本的验证。除了非常慢,这可以在极少数情况下触发MSI自我修复。这可能是一个小包或类似的东西 - 比如Visual Studio。在大多数情况下,这种情况不会发生 - 但存在风险。不要在重要会议之前运行此命令 - 它不是危险的(它是只读的),但它可能导致在非常罕见的情况下进行长时间修复(我认为你也可以取消自我修复 - 除非有问题的包主动阻止,但如果你再次调用Win32_Product它会重新启动,这将持续到你让自修复完成 - 有时它可能会继续,即使你让它完成:How can I determine what causes repeated Windows Installer self-repair?)。

并且只是为了记录:some people report their event logs filling up with MsiInstaller EventID 1035 entries(参见代码主管的答案) - 显然是由Win32_Product类的WMI查询引起的(我个人从未见过这个)。这与上面建议的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运行的广泛部分:How can I find the Upgrade Code for an installed MSI file?。它似乎是防火墙规则,通过注册表调整来抑制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 flavor):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并按“执行”。 屏幕截图跳过,应用程序需要太多的屏幕空间。
  2. 最后,您可以尝试使用VBScript通过MSI自动化界面访问信息(Windows的核心功能 - 它与WMI无关)。 复制以下脚本并粘贴到桌面上的* .vbs文件中,然后尝试通过双击运行它。您的桌面必须是可写的,或者您可以使用任何其他可写位置。 这不是一个很棒的VBScript。 Terseness比错误处理和完整性更受欢迎,但它应该以最小的复杂性完成工作。 输出文件在您运行脚本的文件夹中创建(文件夹必须是可写的)。输出文件名为msiinfo.csv。 双击要在电子表格应用程序中打开的文件,在导入时选择逗号作为分隔符 - 或者 - 只需在记事本或任何文本查看器中打开该文件。 在电子表格中打开将允许高级排序功能。 这个脚本可以很容易地适应显示a significant amount of further details about the MSI installation。可以在这里找到这方面的演示:how to find out which products are installed - newer product are already installed 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

我想不出目前检索产品代码的任何其他通用选项,如果您知道,请添加。只需编辑内联而不是添加太多评论。

您当然可以通过调用the MSI automation interface(基于COM)或C++ MSI installer functions(Win32 API)从您的应用程序中访问此信息。甚至可以在应用程序中使用WMI查询,就像使用PowerShellwbemtest.exeWMIExplorer.exe在上面的示例中一样。


卸载MSI包

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

选项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包的各种不同方法):Uninstalling an MSI file from the command line without using msiexec。有许多不同的卸载方法。

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

以及msiexec.exe (command line options)的快速链接(来自MSDN的msiexec.exe命令行概述)。和the Technet version一样。


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

更新:请找到a new answer on how to find the upgrade code for installed packages而不是手动查找MSI文件中的代码。对于已安装的软件包,这更加可靠。如果未安装软件包,您仍需要查看MSI文件(或用于编译MSI的源文件)以查找升级代码。留在下面的旧版部分:

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

要打开缓存的MSI文件,请使用Orca或其他打包工具。以下是对不同工具的讨论(其中任何一种都可以):What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc。如果您没有安装这样的工具,您最快的赌注可能是尝试Super Orca(它使用简单,但我没有经过广泛的测试)。

更新:这是一个新的答案,其中包含可用于查看MSI文件的各种免费产品的信息:How can I compare the content of two (or more) MSI files?

如果您安装了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。如果您这样做,请在此处编辑和添加详细信息。



类似的主题(供参考和轻松访问 - 我应该清理这个列表):


0
投票

如果你有太多的安装程序来轻松找到你想要的东西,这里有一些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
© www.soinside.com 2019 - 2024. All rights reserved.