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

查看:81
本文介绍了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文件(主要升级-本质上是先卸载产品的现有版本,然后再安装最新版本.

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的产品代码:

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自动化界面公开.如果您platform invoke可以使用该调用-第14节中的C ++示例在此处:

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天全站免登陆