Powershell:通过 UpgradeCode 卸载应用程序 [英] Powershell: Uninstall application by UpgradeCode

查看:16
本文介绍了Powershell:通过 UpgradeCode 卸载应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我通过 Powershell 脚本升级/降级我的应用程序时,我想在运行新安装程序之前先强制卸载当前安装的版本.

When I upgrade / downgrade my application via a Powershell script, I want to first force the uninstallation of the currently installed version before running the new installer.

如何使用 Powershell 使用应用程序的 UpgradeCode 执行此操作?

How can I do that with Powershell, using the UpgradeCode of the application?

按应用程序名称进行操作会不太可靠.

Doing it by application name would be less robust.

推荐答案

既然你提到升级代码,那一定意味着你在谈论一个 MSI 文件 (Windows 安装程序).正如其他人所说,这样的卸载通常由正确创作的 MSI 包自动神奇地执行 - 它被称为 重大升级 - 这实质上是卸载产品的现有版本,然后安装最新版本.

Since you mention upgrade code, it must mean that you are talking about an MSI file (Windows Installer). As stated by others such an uninstall is normally performed auto-magically by a properly authored MSI package - it is referred to as a major upgrade - which is essentially an uninstall of the existing version of a product and then the install of the newest version.

升级表<正在安装的 MSI 的/a> 将指定在安装新版本之前将卸载框中的哪些现有软件包.理论上,您可以卸载任意数量的现有安装.如果您像帽匠一样生气,您甚至可以卸载竞争产品.坦率地说,令人惊讶的是,我从未尝试在一次重大升级期间卸载多个产品 - 很少需要这样做.在大多数情况下,您卸载单个现有产品,然后安装最新版本.

The Upgrade Table of the MSI being installed will specify what existing packages on the box will be uninstalled before the new version is installed. In theory you can uninstall any number of existing installations. You can even uninstall a competitive product if you are mad as a hatter. Frankly, and astonishingly, I have never tried to uninstall multiple products during one major upgrade - it is rarely called for. In most cases you uninstall a single, existing product and then install your latest version.

  1. 您可以使用 转换 以更改主要升级的行为方式 - 换句话说,使其开始或停止卸载特定的预先存在的安装.

  1. You can modify the Upgrade table using a transform to change how the major upgrade behaves - in other words to make it start or stop uninstalling a specific pre-existing installation.

您还可以通过调用此 MSI API 函数(COM - VBScript 用作示例)来枚举共享相同升级代码的所有相关产品:

You can also enumerate all related products that share the same upgrade code by calling this MSI API function (COM - VBScript used as sample):

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 自动化执行此操作,请参见下文):

Then you can uninstall the products by passing the product code(s) to the msiexec.exe command line (see below for how to do this via MSI API COM automation instead):

msiexec.exe /x {11111111-1111-1111-1111-11111111111X} /L*V "C:msilog.log" REBOOT=ReallySuppress

快速参数说明(因为我推荐这个选项):

Quick Parameter Explanation (since I recommend this option):

 /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 的命令行中的文件.


If you don't want to uninstall via msiexec.exe, then you can find a myriad of ways to invoke an MSI uninstall here: Uninstalling an MSI file from the command line without using msiexec.

您可以通过多种不同方式找到已安装 MSI 的产品代码:如何找到已安装的 MSI 设置的产品 G​​UID?

And you can find the product code of an installed MSI in several different ways: How can I find the product GUID of an installed MSI setup?

更新:我想我忘记了显而易见的,您可以通过 MSI API 自动化直接卸载.在下面的脚本中,我们让所有产品共享相同的升级代码,然后依次卸载它们.

UPDATE: I guess I forgot the obvious, you can uninstall directly via MSI API automation. In the script below we get all products sharing the same upgrade code and then uninstall them in sequence.

请注意,当静默运行时,您应该以管理员权限运行,因为 UAC 可能会被抑制,然后卸载通常会失败(权限被拒绝).因此,下面的脚本以交互方式运行卸载 - 允许 UAC 提示和提升.

Note that when run silently you should run with admin rights since the UAC may be suppressed and then the uninstall will usually fail (permission denied). Because of this the below script runs the uninstall interactively - allowing UAC prompting and elevation.

如果不明显:运行此脚本将卸载 Orca!我使用此产品作为示例,因为它可以快速再次安装(如果您需要在此处快速找到安装程序的提示 - 搜索逆戟鲸"):

And if it isn't obvious: running this script will uninstall Orca! I use this product as a sample because it is quick to install again (hints on finding the installer quick if you need to towards bottom here - search for "orca"):

重要免责声明:

COM 方法installer.ConfigureProduct 不接受任何允许我们传入REBOOT=ReallySuppress 的参数.这意味着一个(非常)编写不当的包会触发 ScheduleReboot 操作(或使用一些更晦涩的魔法来导致重新启动) - 如果您以管理员权限和静默模式运行以下脚本,则可能会在没有警告的情况下重新启动系统.

The COM method installer.ConfigureProduct does not accept any arguments that allow us to pass in REBOOT=ReallySuppress. This means that a (very) badly authored package which triggers the ScheduleReboot action (or uses some more obscure magic to cause a reboot) - may reboot the system without warning if you run the below script with admin rights and in silent mode.

有一个更新的调用 ConfigureProductEx,它可用作 Win32 函数,但它通过 COM 自动化接口公开.如果您平台调用,您可以使用该调用 - 第 14 节中有一个 C++ 示例:不使用 msiexec 从命令行卸载 MSI 文件.或者,您可以使用 WiX 工具包中的 DTF 功能(请参阅与 C++ 示例相同的链接中的第 6 节).

There is a newer call ConfigureProductEx which is available as a Win32 function, but it is not exposed via the COM automation interface. If you platform invoke you can use that call - there is a C++ example in section 14 here: Uninstalling an MSI file from the command line without using msiexec. Or you can use the DTF feature from the WiX toolkit (see section 6 in the same link as the C++ example).

2018 年 7 月更新:

Set installer = CreateObject("WindowsInstaller.Installer")
installer.InstallProduct "product.msi", "REMOVE=ALL REBOOT=ReallySuppress"
Set installer = Nothing

也许上面的代码片段是最好的卸载方法?这应该会抑制任何重新启动.我现在没有时间或设置来测试它(在 Linux 机器上),但我想在我忘记之前添加它.

Perhaps the above snippet is the best uninstall approach? This should suppress any reboots. I don't have the time or the setup to test it right now (on a Linux box), but I wanted to add it before I forget.

原始卸载脚本:

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

<小时>

一些链接:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆