我需要找到已安装的MSI文件的产品GUID,以便执行patching
,uninstall
(how-to uninstall)以及auditing purposes
等维护。
对于升级代码检索:How can I find the Upgrade Code for an installed MSI file?
以下信息随着时间的推移而大大增加,可能会变得有点过于复杂。如何快速获得产品代码? (四种方法):
Use the Powershell "one-liner"
向下滚动屏幕截图并逐步显示。免责声明也低于 - 轻微或中等风险取决于您的要求。对我来说工作正常。通常应该可以取消由此选项触发的任何自我修复。触发的包完整性检查确实添加了一些事件日志“噪音”。注意! IdentifyingNumber
是ProductCode
(WMI的特点)。
get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
快速启动Powershell:按住Windows键,点击R,输入“powershell”并按Enter键
Use VBScript
在“替代工具”(第3节)下描述。由于下面详细说明的原因,此选项可能比Powershell更安全。本质上它(更快)并且不能触发MSI自修复,因为它不通过WMI(它以极快的速度直接访问MSI COM API)。但是,它比Powershell选项(几行代码)更复杂。
Registry Lookup
有些人发誓要在注册表中查找内容。不是我推荐的方法 - 我喜欢通过适当的API(或者换句话说:OS函数调用)。只有API实现的内部才会有奇怪的异常:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall
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 - 它快速而灵活(但也可以锁定在某些机器上,脚本编写总是比使用工具更复杂)。
wbemtest.exe
。
启动wbemtest.exe
(按住Windows键,点击R,释放Windows键,输入“wbemtest.exe”并按OK)。
单击“连接”,然后单击“确定”(命名空间默认为root \ cimv2),再次单击“连接”。
单击“查询”并键入此WQL命令(SQL flavor):SELECT IdentifyingNumber,Name,Version FROM Win32_Product
并单击“使用”(或等效 - 该工具将被本地化)。
示例输出截图(截断)。不是最好的格式,但您可以获得所需的数据。 IdentifyingNumber是MSI产品代码:WMIExplorer.exe
这不包括在Windows中。然而,这是一个非常好的工具。推荐的。
请查看:https://github.com/vinaypamnani/wmie2/releases
启动该工具,单击“连接”,双击“ROOT \ CIMV2”
从“查询选项卡”中,键入以下查询SELECT IdentifyingNumber,Name,Version FROM Win32_Product
并按“执行”。
屏幕截图跳过,应用程序需要太多的屏幕空间。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查询,就像使用
PowerShell
,wbemtest.exe
或WMIExplorer.exe
在上面的示例中一样。
如果要执行的操作是卸载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一样。
更新:请找到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。如果您这样做,请在此处编辑和添加详细信息。
类似的主题(供参考和轻松访问 - 我应该清理这个列表):
如果你有太多的安装程序来轻松找到你想要的东西,这里有一些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