Set installer = CreateObject("WindowsInstaller.Installer")
' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"
' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
For Each u In upgrades
MsgBox u, vbOKOnly, "Product Code: "
Next
然后,您可以通过将产品代码传递到msiexec.exe命令行来卸载产品(有关如何通过MSI API COM自动化来完成此操作,请参见下文):
Const msiUILevelNone = 2
Const msiInstallStateAbsent = 2
Set installer = CreateObject("WindowsInstaller.Installer")
'installer.UILevel = msiUILevelNone ' Disabled to prevent silent uninstall. Now the UAC prompt will show
' Uninstall Orca, replace upgrade code with yours
Set products = installer.RelatedProducts("{CFF4D510-79B2-1CCD-0061-5741A0565A76}")
For Each product In products
' MsgBox "Product Code: " & product ' Show the product code found, if you want
' The following call when run silently with admin rights may reboot the system without warning!
' This is due to badly authored MSI packages - most packages will not trigger this problem.
installer.ConfigureProduct product, 0, msiInstallStateAbsent ' Uninstall product
' See text above for info on the newer ConfigureProductEx method.
Next
Set installer = Nothing
MsgBox "Finished" ' Just so we know the script ran if nothing found to uninstall
2条答案
按热度按时间3pvhb19x1#
既然你提到了升级代码,那就意味着你在谈论一个MSI文件(Windows Installer)。正如其他人所说的那样,这样的卸载通常是由一个正确创作的MSI包自动执行的-它被称为major upgrade-它本质上是卸载现有版本的产品,然后安装最新版本。
正在安装的MSI的Upgrade Table将指定在安装新版本之前,盒子上的哪些现有软件包将被卸载。理论上,你可以卸载任何数量的现有安装。如果你疯了,你甚至可以卸载竞争产品。坦率地说,令人惊讶的是,我从来没有尝试过在一次重大升级过程中卸载多个产品-很少要求这样做。大多数情况下,你卸载一个现有的产品,然后安装你的最新版本。
1.您可以使用transform修改Upgrade表以更改主要升级的行为方式-换句话说,使其开始或停止卸载特定的预先存在的安装。
1.您还可以通过调用以下MSI API函数(COM - VBScript用作示例)来枚举共享相同升级代码的所有相关产品:
然后,您可以通过将产品代码传递到msiexec.exe命令行来卸载产品(有关如何通过MSI API COM自动化来完成此操作,请参见下文):
快速参数解释(因为我推荐此选项):
如果您不想通过
msiexec.exe
卸载,那么您可以在这里找到无数种调用MSI卸载的方法:不使用msiexec从命令行卸载MSI文件。您可以通过几种不同的方式找到已安装MSI的产品代码:如何找到已安装MSI安装程序的产品GUID?
更新:我想我忘记了一个显而易见的事实,你可以通过MSI API自动化直接卸载。在下面的脚本中,我们得到了所有共享相同升级代码的产品,然后按顺序卸载它们。
请注意,当静默运行时,您应该使用管理员权限运行,因为UAC可能会被抑制,然后卸载通常会失败(权限被拒绝)。因此,下面的脚本以交互方式运行卸载-允许UAC提示和提升。
如果还不明显:**运行此脚本将卸载Orca!**我使用此产品作为示例,因为它可以快速再次安装(如果您需要在此处底部快速查找安装程序的提示-搜索“orca”):
重大免责声明:
COM方法
installer.ConfigureProduct
不接受允许我们传入REBOOT=ReallySuppress
的任何参数。这意味着如果您以管理员权限并在静默模式下运行以下脚本,则触发ScheduleReboot操作(或使用一些更晦涩的魔法导致重新启动)的(非常)错误编写的软件包-可能会在没有警告的情况下重新启动系统 *。有一个更新的调用
ConfigureProductEx
,它可以作为一个Win32函数使用,但是它不**通过COM自动化接口公开。如果你使用platform invoke
,你可以使用这个调用-在第14节有一个C示例:不使用msiexec从命令行卸载MSI文件,或者使用WiX工具包中的DTF特性(参见C示例链接中的第6节)。2018年7月更新:
也许上面的代码片段是最好的卸载方法?这应该会抑制任何重新启动。我没有时间或设置来测试它现在(在Linux机器上),但我想添加它之前,我忘记了。
原始卸载脚本:
部分链接:
8i9zcol22#
因为这个问题特别提到了powershell,我也把它放在这里。还有其他的PS解决方案围绕着使用WMI和/或Get-Package。这个解决方案基于https://outnull.wordpress.com/2016/11/02/uninstalling-application-based-on-upgradecode/,但接受各种形式的升级代码语法,并且它试图避免在转换到/从包/升级Guid和注册表表示时的字符串操作。