【问题标题】:How to disable a particular CustomAction for previously installed version during an upgrade installation with MSI database?如何在使用 MSI 数据库进行升级安装期间禁用先前安装版本的特定 CustomAction?
【发布时间】:2022-01-22 20:18:54
【问题描述】:

我有一个软件包,其先前安装的版本包含一系列设计不佳的自定义操作:它们执行的操作可以开箱即用。因此,我将删除这些以供将来的版本使用。
这些自定义操作的条件会导致一系列错误 - 它们都在升级期间的卸载步骤中第二次运行。为了规避不良行为,我想提供一个自定义操作,如果检测到某个应用程序,它会修改以前安装的应用程序的数据库。

给定应用程序名称、版本和自定义操作名称,如何在升级时的自定义操作期间为卸载步骤禁用它?


当我在升级安装期间在 C++ 自定义操作中运行我的代码时,我尝试修改自定义操作条件失败:MsiOpenDatabaseW throws access violation when executed within an msi custom action
基本上我使用MsiOpenDatabaseW 来修改缓存的msi 数据库。它在独立可执行文件中运行时有效,但在自定义操作中会导致访问冲突。

【问题讨论】:

  • 造成麻烦的具体情况是什么?
  • @SteinÅsmul 条件本身与问题无关,当使用MsiOpenDatabaseW 和查询命令运行独立 exe 时,我可以使用 MSI 数据库查询成功修复它。问题是MsiOpenDatabaseW在运行安装过程中无法运行stackoverflow.com/questions/70660365/…
  • 如果您使用自己的属性 - 换句话说,它不是 MSI 本身的内置属性 - 也许您可以使用自定义操作修改其值以确保条件为假,因此有问题的自定义操作不运行?这只有在特殊情况下才有可能,而且当您采取变通办法时,总是有可能出现新错误。
  • @SteinÅsmul 正如我所说,我可以在卸载步骤中成功修改 cached 安装程序的自定义操作条件以生成 false。问题是在重大升级安装期间在自定义操作中运行MsiOpenDatabaseW 时收到段错误。我已经链接了相关问题。
  • 有关由于对话框或自定义操作意外运行而导致的卸载问题的链接显示了如何轻松使用次要升级补丁在调用之前修复已安装产品的卸载顺序 - 问题是 the delivery method for the patch

标签: c++ windows-installer


【解决方案1】:

我推荐的更简单的解决方案是手动修复计算机上的状况并重建 MSI。

然后获取此 MSI 并将其包含在您的应用程序的下一个版本中,并在 RemoveExistingProduct 标准操作之前对 re-cache it 运行自定义操作。

msiexec /fv <path of the fixed msi>

这样,在触发升级之前,错误条件的安装程序会被重新缓存,您无需编写代码直接修改缓存的MSI

【讨论】:

  • 这不是一个选项。有些客户安装了无法简单重建的各种以前的版本(项目很大,有很多令人费解的遗留代码)。最简单的解决方案是自定义修改操作
【解决方案2】:

您需要为缓存(已安装)MSI 的自定义操作修改 InstallExecuteSequence/InstallUISequence 的“条件”。可以在这里找到一个示例,它根据 ProductCode 搜索缓存的 MSI,并在 InstallExecuteSequence 中修改自定义操作的条件:

https://www.alkanesolutions.co.uk/2012/12/08/editing-msi-files-in-the-windows-installer-cache/

【讨论】:

  • 这正是我的意思。但是在 VBA 中的例子。我应该在修改自定义操作时使用什么 C++ API?
  • 我可以使用现有的 MSI HANDLE 作为参数传递给我的自定义操作来进行搜索吗?
  • 例如,如果您将其作为主要升级的一部分,您需要在 RemoveExistingProducts 之前运行您的操作。我认为在该操作期间没有办法控制升级 MSI。最好的办法是查询特定 Session 对象的 Upgrade 表,遍历 ProductCode(s) 或以前的版本,并修改缓存的 MSI(如果存在)。
  • 我认为您可以获得当前会话的 MSIHANDLE(如果您的自定义操作是即时的),但不能获得另一个 MSI 的会话。 docs.microsoft.com/en-us/windows/win32/msi/…
  • 我想我可以 MsiOpenDatabaseA 使用缓存的 .msi 的路径,我会以某种方式从 ProductCode
猜你喜欢
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
相关资源
最近更新 更多