对于升级代码的检索。 https://stackoverflow.com/questions/46637094/how-can-i-find-the-upgrade-code-for-an-installed-msi-file/46637095#46637095
简短版本
下面的信息随着时间的推移有了很大的增长,可能变得有些过于详尽。如何快速获得产品代码?(四个方法)。 1.
使用Powershell "one-liner"
。向下滚动查看截图和步骤。免责声明也在下面--轻微或中等风险,取决于你问谁。对我来说,工作正常。由这个选项触发的任何自我修复一般都可以取消。触发的包完整性检查确实增加了一些事件日志"噪音",不过。注意!识别码 "是***的 "产品代码"(WMI的特殊性)。
get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
使用VBScript
。有些人发誓要在注册表中查找东西。这不是我推荐的方法--我喜欢通过适当的API(或者换句话说:操作系统功能调用)。总是有一些奇怪的例外情况,只能由API实现的内部来解释。
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
。HKLM\SOFTWARE\WOW6432Node\MicrosoftWindowsCurrentVersion\Uninstall
。HKCUSoftwareMicrosoftWindowsCurrentVersion\Uninstall
。
4.Original MSI File / WiX Source`s你可以在任何MSI文件的属性表
中找到产品代码
(也可以是任何其他属性)。然而,GUID有可能(很少)被安装时应用的转换所覆盖,因此不符合产品注册的GUID(上述方法1和2将报告真正的产品代码--在Windows注册的--在这种罕见的情况下)。
你需要一个工具来查看MSI文件。请看下面答案的底部,你可以下载的免费工具的清单(或看下面的快速选项):https://stackoverflow.com/questions/48482545/how-can-i-compare-the-content-of-two-or-more-msi-files/48482546#48482546
更新。为了方便和速度的需要:-),从这个直接下载的热链下载SuperOrca,不要拖延和大惊小怪--这个工具足以完成工作--安装,打开MSI,直接进入属性表,找到ProductCode
行(请经常对直接下载的热链进行病毒检查--显然-你可以用virustotal.com来做 - 在线扫描利用几十个反病毒和恶意软件套件来扫描你上传的内容)。
Orca是微软自己的工具,它被安装在Visual Studio和 Windows SDK。尝试搜索
Orca-x86_en-us.msi
- 在Program Files (x86)
并安装MSI(如果找到)。在下面你会发现原始答案,它"有机地发展"到很多细节。 如果这是你需要执行的任务,也许请看下面的"卸载MSI包"部分。
检索产品代码
更新。如果你还需要升级代码,请查看这个答案。 https://stackoverflow.com/questions/46637094/how-can-i-find-the-upgrade-code-for-an-installed-msi-file/46637095#46637095 (检索相关的产品代码、升级代码& 产品名称在 一个表格输出 - 类似于下面的表格)。
- 不能使用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。 如果你需要对很多远程计算机远程运行这个查询*,请参阅下面的"从远程计算机检索产品代码*"部分。
免责声明(很重要,请在运行该命令前阅读!)。由于微软的奇怪设计,任何对
Win32_Product
的WMI调用 的任何WMI调用(如下面的PowerShell命令)都会触发验证的 包遗产的。除了*相当慢之外,这在极少数情况下会 触发MSI自我修复。这可以是一个小包,也可以是一些 巨大的--比如Visual Studio。在大多数情况下,这不会发生 - 但是 有一个风险。不要在一个重要的会议之前运行这个命令。 召开会议之前运行这个命令--它并不危险(它是只读的),但它可能会 在极少数情况下会导致长时间的修复*(我想你可以取消 自我修复--除非被有关软件包主动阻止,但如果你调用Win32_Product 就会重新启动,这将持续到你让自我修复完成为止--有时即使你让它完成,它也可能继续下去:https://stackoverflow.com/questions/5501028/how-can-i-determine-what-causes-repeated-windows-installer-self-repair/6066263#6066263)。而且只是为了记录。有些人报告说他们的事件日志中充满了MsiInstaller EventID 1035条目(见代码主管的回答)--显然是由对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)的影响(加上任何额外的非微软因素--例如真实防火墙、第三方软件防火墙、各种安全软件等)。它是否能工作,取决于你的具体设置。
PowerShell需要安装.NET框架(目前似乎是3.5.1版本? 2017年10月)。即使安装了.NET,实际的PowerShell应用程序本身也可能从机器上消失。最后,我相信PowerShell可以通过各种系统策略和权限被禁用或锁定。
如果是这种情况,你可以尝试其他一些方法来检索产品代码。我首选的替代方法是VBScript--它既快又灵活(但在某些机器上也可能被锁定,而且编写脚本总是比使用工具要麻烦一些)。
1.让我们从一个**内置的Windows WMI工具开始。wbemtest.exe
。
wbemtest.exe
(按住Windows键,点击R,释放Windows键,输入"wbemtest.exe"并按OK)。WMIExplorer.exe
。SELECT IdentifyingNumber,Name,Version FROM Win32_Product
,然后按执行。msiinfo.csv
。' 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
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。静默卸载,并有verbose日志记录(对批处理文件更好)。
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的源文件)来寻找升级代码。留在下面的旧部分。 如果你想获得升级代码或其他MSI属性,你可以从上图中"LocalPackage"指定的位置打开该产品的缓存安装MSI(类似于。
C:\WINDOWS\Installer\50c080ae.msi
- 这是一个十六进制文件名,在每个系统上都是唯一的)。然后你在"属性表"中查找UpgradeCode(UpgradeCode有可能在转换中被重新定义--为了确保你得到正确的值,你需要从系统中以编程方式检索该代码--我将很快提供一个脚本。然而,在缓存的MSI中发现的UpgradeCode通常是正确的)。 要打开缓存的MSI文件,请使用Orca或其他打包工具。这里有一个关于不同工具的讨论(任何一个都可以):https://stackoverflow.com/questions/1544292/what-installation-product-to-use-installshield-wix-wise-advanced-installer/1546941#1546941。如果你没有安装这样的工具,你最快的选择可能是尝试[Super Orca]4(它使用起来很简单,但没有经过我的广泛测试)。 更新:这里有一个新的答案,包括各种免费产品的信息,你可以用来查看MSI文件:https://stackoverflow.com/questions/48482545/how-can-i-compare-the-content-of-two-or-more-msi-files/48482546#48482546 如果你安装了Visual Studio,试着搜索`Orca-x86_en-us.msi
- 在Program Files (x86)
下 - 并安装它(这是微软自己的官方MSI查看器和编辑器)。然后在开始菜单中找到Orca。很快就可以开始了:-)。技术上来说,Orca是作为Windows SDK的一部分安装的(而不是Visual Studio),但Windows SDK是与Visual Studio安装捆绑在一起的。如果你没有安装Visual Studio,也许你知道有人会安装?只要让他们搜索这个MSI并发送给你(它是一个很小的半mb文件)--应该需要几秒钟。更新:你需要几个CAB文件以及MSI--这些文件在找到MSI的同一文件夹中。如果没有,你可以随时下载Windows SDK(它是免费的,但它很大--而且你安装的所有东西都会拖慢你的电脑)。我不确定SDK的哪一部分安装了Orca MSI。如果你知道,请在这里编辑并添加详细信息。
类似的主题(供参考和方便访问 - 我应该把这个列表清理一下)。
如果你有太多的安装程序,无法轻易找到你要找的东西,这里有一些powerhell,可以提供一个过滤器,通过显示名称缩小范围。
$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