既然您提到升级代码,那么它一定意味着您正在谈论 MSI 文件(Windows安装程序)。正如其他人所述,此类卸载通常是由正确编写的 MSI 包自动执行的 - 它被称为主要升级- 这本质上是卸载产品的现有版本,然后安装最新版本。
The 升级表正在安装的 MSI 的名称将指定在安装新版本之前将卸载盒子上的哪些现有软件包。理论上,您可以卸载任意数量的现有安装。如果你疯了,你甚至可以卸载竞争产品。坦率地说,令人惊讶的是,我从未尝试在一次重大升级期间卸载多个产品 - 很少有人这样做。在大多数情况下,您会卸载单个现有产品,然后安装最新版本。
您可以使用以下命令修改升级表转换更改主要升级的行为方式 - 换句话说,使其启动或停止卸载特定的预先存在的安装。
您还可以通过调用此 MSI API 函数(以 COM - VBScript 作为示例)来枚举共享相同升级代码的所有相关产品:
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 自动化执行此操作,请参阅下文):
msiexec.exe /x {11111111-1111-1111-1111-11111111111X} /L*V "C:\msilog.log" REBOOT=ReallySuppress
快速参数解释(因为我推荐这个选项):
/X = run uninstall sequence
/QN = run completely silently
/L*V "C:\msilog.log"= verbose logging at path specified
{11111111-1111-1111-1111-11111111111X} = product guid of app to uninstall
REBOOT=ReallySuppress = prevent reboot without warning (badly authored MSI packages)
如果您不想通过卸载msiexec.exe
,那么您可以在此处找到多种调用 MSI 卸载的方法:从命令行卸载 MSI 文件而不使用 msiexec.
您可以通过多种不同的方式找到已安装 MSI 的产品代码:如何找到已安装的 MSI 设置的产品 GUID?
UPDATE:我想我忘记了显而易见的事情,您可以直接通过 MSI API 自动化卸载。在下面的脚本中,我们让所有产品共享相同的升级代码,然后按顺序卸载它们。
请注意,当静默运行时,您应该使用管理员权限运行,因为 UAC 可能会被抑制,然后卸载通常会失败(权限被拒绝)。因此,下面的脚本以交互方式运行卸载 - 允许 UAC 提示和提升。
如果不明显的话:运行此脚本将卸载 Orca!我使用这个产品作为示例,因为它再次安装很快(如果您需要在此处找到安装程序,请参阅快速找到安装程序的提示- 搜索“逆戟鲸”):
重要免责声明:
COM方法installer.ConfigureProduct
不接受任何允许我们传入的参数REBOOT=ReallySuppress
。这意味着一个(非常)编写得很糟糕的包会触发 ScheduleReboot 操作(或使用一些更晦涩的魔法来导致重新启动) -如果您以管理员权限并在静默模式下运行以下脚本,可能会在没有警告的情况下重新启动系统.
有一个新的电话ConfigureProductEx
它可以作为 Win32 函数使用,但它是not通过 COM 自动化接口公开。如果你platform invoke
您可以使用该调用 - 第 14 节中有一个 C++ 示例:从命令行卸载 MSI 文件而不使用 msiexec。或者,您可以使用 WiX 工具包中的 DTF 功能(请参阅与 C++ 示例相同的链接中的第 6 节)。
2018 年 7 月更新:
Set installer = CreateObject("WindowsInstaller.Installer")
installer.InstallProduct "product.msi", "REMOVE=ALL REBOOT=ReallySuppress"
Set installer = Nothing
也许上面的代码片段是最好的卸载方法?这应该会抑制任何重新启动。我现在没有时间或设置来测试它(在 Linux 机器上),但我想在忘记之前添加它。
原始卸载脚本:
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
一些链接:
-
使用 msiexec 卸载应用程序时是否有 GUID 的替代方案?(按产品名称卸载)
- 如何使用 PowerShell 卸载应用程序?
- 如何使用 powershell 运行安装程序?
- WIX(删除所有以前的版本)
-
Wix升级进入维护模式并且永远不会升级(各种卸载方式,通过产品代码、通过升级代码等...)