Powershell:通过 UpgradeCode 卸载应用程序

2023-12-05

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

如何使用应用程序的 UpgradeCode 使用 Powershell 来做到这一点?

通过应用程序名称执行此操作会不太健壮。


既然您提到升级代码,那么它一定意味着您正在谈论 MSI 文件(Windows安装程序)。正如其他人所述,此类卸载通常是由正确编写的 MSI 包自动执行的 - 它被称为主要升级- 这本质上是卸载产品的现有版本,然后安装最新版本。

The 升级表正在安装的 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 设置的产品 G​​UID?


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升级进入维护模式并且永远不会升级(各种卸载方式,通过产品代码、通过升级代码等...)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Powershell:通过 UpgradeCode 卸载应用程序 的相关文章

随机推荐

  • 如何使用jquery删除所有cookie[重复]

    这个问题在这里已经有答案了 可能的重复 使用javascript清除所有cookie 我希望分配一个复选框来一次性激活和清除以前存储在我的表单中的所有 cookie 我该如何使用 jquery cookie 插件来做到这一点 我似乎无法在克
  • 常量构造函数

    在C 中是否可以实现类似于构造函数之类的只允许创建的东西const物体 我正在考虑为接口创建一个装饰器类const和非const方法 从 a 初始化装饰器const基对象应该只能生成 const 装饰器 但从非 const 初始化应该会产生
  • 为什么这段代码会崩溃?

    以下代码会导致堆栈溢出 但我不明白为什么 int tmain int argc TCHAR argv cout lt lt start char bmp 1024 768 3 for int p 0 p lt 9000 p for int
  • 读取网页内容

    你好 我想使用java读取包含德语字符的网页内容 不幸的是 德语字符显示为奇怪的字符 请提供任何帮助 这是我的代码 String link some german link URL url new URL link BufferedRead
  • 如何设置Spark Kmeans初始中心

    我正在使用 Spark ML 来运行 Kmeans 我有一堆数据和三个现有中心 例如这三个中心是 1 0 1 0 1 0 5 0 5 0 5 0 9 0 9 0 9 0 那么我如何表明 Kmeans 中心是上述三个向量 我看到 Kmean
  • Ionic-Framework (4) - Openlayers 地图不工作/不可见

    我尝试将 Openlayers 与 Ionic 一起使用 但地图在 setTimeout 之前不可见 这是我的工作代码 import Component OnInit from angular core import OlMap from
  • 找不到类型或命名空间

    我目前正在尝试将 Visual Studio 2008 中的 WiX 3 5 自定义操作项目转换为 WiX 3 7 和 Visual Studio 2012 但出现以下异常 找不到类型或名称空间名称 MyNamespace 您是 缺少 us
  • 页面加载时,如何让六个函数互相执行?

    当页面加载时 在一个大div中 有六个不同的元素 这些元素有六个不同的函数 我想让这些函数在一定时间后互相执行 例如1000ms 但这六个函数不是绑定到一个元素 它们绑定到六个不同的元素 例如 当页面加载时 我想将Class line1 添
  • 如何使 在 div 内垂直居中? [复制]

    这个问题在这里已经有答案了 代码 div style border solid 1px gray width 400px padding 0px span style background e2e6f0 padding right 4px
  • Apache Commons 文件上传 - 流意外结束

    好吧 我不得不说 到目前为止 这个问题让我难住了 我们在 Tomcat 6 0 18 中运行的 Web 应用程序在文件上传期间失败 但是仅当客户端机器是Windows机器时 仅适用于某些机器 并且适用于所有浏览器 而不仅仅是IE 日志中有堆
  • 将函数应用于列表的每个元素[重复]

    这个问题在这里已经有答案了 假设我有一个类似的列表 mylis this is test another test 如何将函数应用于列表中的每个元素 例如 我该如何申请str upper to get THIS IS TEST ANOTHE
  • 如何在 C# 中执行 SHA1 文件校验和?

    我该如何使用SHA1CryptoServiceProvider 在文件上创建文件的 SHA1 校验和 using FileStream fs new FileStream C file location FileMode Open usin
  • python exec() 中的全局变量和局部变量

    我正在尝试使用 exec 运行一段 python 代码 my code class A object pass print locals s locals print A s A class B object a ref A global
  • 创建确定性有限自动机 (DFA) - Mercury

    我想要在 Mercury 中模拟确定性有限自动机 DFA 但我有几个地方很糟糕 形式上 DFA 具有以下特征 一组状态 S 一个输入字母 E 一个转换函数 S E gt S 一个startState s S setOfAcceptableF
  • Java [unchecked] 未检查的情况警告

    好吧 我环顾四周并做了很多谷歌搜索 但我仍然找不到避免此警告的方法 Integer result chooser showOpenDialog null if result equals 0 String tempHolder choose
  • 无法更改 Android 设备中的语言

    我正在尝试在应用程序中更改设备的语言 我有这个代码 Locale locale new Locale en US Locale setDefault locale Configuration config new Configuration
  • Python:访问另一个文件中函数中的变量

    我有两个文件 lib py global var def test var Hello return test py from lib import test print var 但是尽管它们位于同一文件夹中 当我运行 test py 时
  • 从按钮扩展获取所有数据 (Excel)

    我们有一个支持分页的数据表 没问题 需要包含 导出到 Excel 按钮 因此 我们添加了 按钮 扩展 并且可以正常导出数据 问题是这样的 它只导出当前页面的数据 而不是整个数据集 如何获取整组数据 是否可以 dataTable custom
  • 需要 WPF 线角度的算法

    计算 WPF 线的角度 以度为单位 的 正确 算法是什么 你需要atan2 然而 这将为您提供以弧度为单位的角度 转换为度数一定很容易 角度的计算方式为atan2 y2 y1 x2 x1 where x1 y1 and x2 y2 是你的线
  • Powershell:通过 UpgradeCode 卸载应用程序

    当我通过 Powershell 脚本升级 降级我的应用程序时 我想在运行新安装程序之前首先强制卸载当前安装的版本 如何使用应用程序的 UpgradeCode 使用 Powershell 来做到这一点 通过应用程序名称执行此操作会不太健壮 既