PowerShell的:通过的UpgradeCode卸载应用程序PowerShell的:通过的Upg

2019-05-12 13:33发布

当我升级/通过PowerShell脚本降级我的申请,我想先迫使当前安装的版本的卸载运行新的安装程序之前。

我怎样才能做到这一点使用PowerShell,使用应用程序的的UpgradeCode?

通过应用程序的名称做这将是不太可靠的。

Answer 1:

既然你提到的升级代码,就一定意味着你是在谈论一个MSI文件( Windows安装程序 )。 正如其他人指出,通常执行这种卸载自动奇迹般地正确撰写MSI包-它被称为一个重大升级 -这基本上是一个产品的现有版本卸载,然后将最新版本安装。

该升级表安装的MSI将指定什么安装新版本之前,包装盒上的现有软件包将被卸载。 从理论上讲,你可以卸载任何现存的安装。 你甚至可以卸载有竞争力的产品,如果你是疯了作为一个帽匠。 坦率地说,和惊人的,我从来没有试过一个重大的升级过程中卸载多个产品 - 它很少要求。 在大多数情况下,你卸载一个,现有的产品,然后安装您的最新版本。

  1. 您可以使用修改升级表变换换句话说,使其启动或停止卸载特定的现有预安装-更改重大升级的行为。

  2. 您也可以通过调用这个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?


更新 :我想我忘了明显的,你可以通过MSI API自动化直接卸载。 在下面的脚本,我们得到的所有产品共享相同的升级代码,然后按顺序将其卸载。

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

如果这不是明摆着: 运行该脚本将卸载的Orca! 我用这个产品作为一个样本,因为它是快速重新安装( 在发现安装快速提示,如果你需要对底部位置 -搜索“逆戟鲸”):

BIG免责声明

该COM方法installer.ConfigureProduct不接受,使我们能够在传递任何参数REBOOT=ReallySuppress 。 这意味着,(很)严重撰写包,它触发ScheduleReboot动作(或使用一些比较模糊的魔法造成重启) - 如果您运行与管理权限,并以静默模式下面的脚本可以重新启动系统,无需警告

有一个新的呼叫ConfigureProductEx这是作为一个Win32函数,但它不是通过COM自动化接口暴露出来。 如果你platform invoke ,您可以使用该调用-有一个C ++例子在这里第14条: 卸载命令行的MSI文件,而无需使用MSIEXEC 。 或者你可以使用从WiX的工具包(请参阅同一条链路C ++例子节6)DTF功能。


UPDATE 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通过安装运行?
  • 维克斯(除去以前的所有版本)
  • 维克斯升级进入维护模式,并且从来不会升级 (各种方式卸载,按产品代码,升级代码,等...)


文章来源: Powershell: Uninstall application by UpgradeCode