【问题标题】:Wix Tools update uses old custom actionsWix 工具更新使用旧的自定义操作
【发布时间】:2017-12-22 12:09:31
【问题描述】:

我们在使用 WIX 设置工具时发现了一些奇怪的行为。 我们已经部署了一些主要版本(2.2.0 - 到 2.2.4)。对于 2.2.5,我们更改了自定义操作中的一些小东西(在我们使用 XCOPY 之前,现在我们使用 RoboCopy,因为它有一个“MOVE”命令而不仅仅是一个副本)。

但是当我们现在从 2.2.4 更新到 2.2.5 时,安装程​​序仍然使用旧的 Copy 命令而不是新的 MOVE 命令,但这不可能是因为 2.2.5 没有任何 Copy 命令。 如果我部署 2.2.6(与 2.2.5 相同)并从 2.2.5 更新,它将使用新的更新过程...... 看起来更新使用的是旧的 MSI。

Found this on SO

有没有办法防止这种行为?这完全破坏了更新过程,因为现有配置文件在更新时未正确复制。

我们不能强制客户通过 GUID 清理注册表或从缓存中删除任何 MSI 文件...

任何帮助表示赞赏。 提前致谢

更新: Product.wxs 中的新自定义操作

<Property Id="C_TEMP" Value="C:\Temp" />
      <Property Id="ROBOCOPY_EXE">robocopy.exe</Property>
      <CustomAction Id="CopyToTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[INSTALLDIR]\Configuration" "[C_TEMP]\ServerSettings" ServerSettings.json' />
      <CustomAction Id="CopyFromTemp" Property="ROBOCOPY_EXE" Return="ignore" ExeCommand='"[C_TEMP]\ServerSettings" "[INSTALLDIR]\Configuration" ServerSettings.json /MOVE /IS' />

旧的自定义操作

<Property Id="C_TEMP" Value="C:\Temp" />
  <Property Id="XCOPY_EXE">xcopy.exe</Property>
  <CustomAction Id="CopyToTemp" Property="XCOPY_EXE" Return="ignore" ExeCommand='"[INSTALLDIR]\Configuration\ServerSettings.json" "[C_TEMP]\ServerSettings.json.bak*" /YIR' />
  <CustomAction Id="CopyFromTemp" Property="XCOPY_EXE" Return="ignore" ExeCommand='"[C_TEMP]\ServerSettings.json.bak" "[INSTALLDIR]\Configuration\ServerSettings.json*" /YIR' />

之后代码至今没有改变

<InstallExecuteSequence>
  <Custom Action="CopyToTemp" Before="InstallInitialize">Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)</Custom>
  <Custom Action="CopyFromTemp" Before="SetVersionsInRegistry">NOT Installed OR Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)</Custom>

.....
</InstallExecuteSequence>

【问题讨论】:

  • 当您升级 MSI 时会运行旧的安装来卸载它。如果您没有在自定义操作上使用正确的条件创作它,它将在卸载期间运行它。当您安装新的 msi 时,您应该能够使用“/l*v msiLog.txt”更好地了解从旧版本升级到 2.2.5+ 的日志发生了什么。您能否将旧的自定义操作定义和时间表以及新的添加到您原来的问题中?
  • 感谢您的解释。我添加了我们更改的自定义操作。但据我了解,设置始终使用已安装版本中的旧自定义操作,而不是新设置。然后我们必须检查是否可以处理此问题..
  • 我已经用新信息更新了我的答案。似乎您对这些自定义操作的条件对于您描述的预期行为并不理想,尽管我并不完全了解它们应该如何工作。请参阅下面的详细信息。
  • 好的,阅读我之前的更新我发现了一些问题。我再次更新了我的答案,这一次我希望并相信新信息会很有用。

标签: wix windows-installer


【解决方案1】:

测试条件

条件 #1:

Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)

这种相当奇怪的条件组合将导致相关自定义操作在全新安装期间不会运行,也不会在手动卸载期间运行。似乎此自定义操作将在以下期间运行:主要升级(这是一种特殊类型的卸载)、修改和修复。我想这可以完成备份设置文件的工作。不过……

在重大升级期间,这确实看起来像是在运行旧的自定义操作,因为正在运行的是您在主要升级模式下的旧包(这是一种特殊的卸载类型) - 因此具有旧包的自定义操作正在运行的是您之前安装的旧缓存数据库 - 作为主要升级的一部分,它会自行卸载)。这些自定义操作在包的初始安装期间从未运行过。但是您要从 temp 复制的其他自定义操作会。这可能不是正确的行为。

总结一下:

  • 运行:主要升级(通过卸载的旧 MSI 运行,但不在新 MSI 中运行)、修改、修复
  • 不运行:第一次安装,卸载。

条件 #2:

NOT Installed OR Installed AND (NOT REMOVE="ALL" OR UPGRADINGPRODUCTCODE)

第二个条件也有点奇怪,似乎只在全新安装和重大升级时运行。您可能只需要在主要升级期间运行它,但您不应该在修复和修改期间也运行它吗? (这些模式在某些情况下也可以覆盖设置文件,例如当 REINSTALLMODE 设置为 "amus" 以强制覆盖文件)。

总结一下:

  • 运行:首次安装,重大升级
  • 不运行:卸载、修改、修复

标准条件

我并不完全了解您的整个场景,但您可以在此处找到几个资源链接以查找常见情况Is it possible to run a custom action only in repair mode。我假设您想在重大升级、修复和修改时备份设置文件以避免它被覆盖。看起来应该对条件进行一些修改才能实现这一点?

我建议完全避免自定义操作,以下是实现此目的的建议方法。


使用应用程序管理设置文件

设置文件的管理和设置一直是部署的难题。几天前我写了一个关于处理用户设置文件的不同方法的简短摘要:Create folder and file on Current user profile, from Admin Profile(这是部署设置文件的不同方法的一点参考 - 推荐,请让我知道是否不清楚)。

从上面的链接答案中可以看出,使用您的应用程序将设置文件从您的安装程序安装的模板副本初始化到 INSTALLDIR 中的只读位置通常是一个好主意。然后,您将保持模板不变,但在启动时,您的应用程序会将您的模板设置文件复制到每个用户的用户配置文件中,或者它只是在 INSTALLDIR 中创建一个安装过程永远不会触及的副本(您需要应用 ACL 权限才能做到这一点所有用户都可以写入的设置文件 - 不是很好的设计,但它确实有效)。 这种基于模板的方法将设置文件与部署注意事项分离。从现在开始,它永远不会被重置、卸载或干预,因为它从未被安装程序安装。事实上,您必须专门实施它的清理或卸载(例如通过 RemoveFolder / RemoveFile 构造),否则它会在卸载时保留在磁盘上 - 这也可能是一个问题。

避免使用 Windows Installer 处理自定义操作的复杂体系结构始终是一个优势。对于您调用的各种二进制文件,存在复杂模拟复杂条件复杂排序以及运行时依赖项。您是使用 DTF 还是直接调用 C# 程序集?使用托管自定义操作存在一些问题(加载了错误的 CLR 版本、根本没有安装 .NET(锁定?)、对 GAC 中的文件的依赖等等......我没有完整的概述 - 我留下了由于这些原因,远离所有用于 MSI 部署的托管代码)。

将模板设置文件复制到安装程序无法触及的新文件时,您不必处理 MSI 的奇思妙想和怪癖 - 或任何托管的自定义操作及其运行时要求。


更新:我删除了我之前添加的传递方法,经过进一步测试后发现它仅在某些情况下有效。我将使用次要升级而不是主要升级再次检查它。然后,您可以使用次要升级补丁来迁移所有旧版本以将设置文件设置为永久,这样它就不会再次被卸载,然后您将应用您的主要升级。这应该可以包含在 Burn bootstrapper 中。

更新:假设(并经过验证)次要升级可以将任何组件切换为永久,并且不需要对组件使用任何传递设置(我没有检查次要更新是否可以如果之前设置为永久,则将组件切换为非永久)。事实上,如果在安装过程中附加到组件的任何条件评估为 false,启用传递性实际上可以卸载组件 - 我没有验证这一点,但从逻辑上讲它是可能的。首先想到的是这是否可以卸载设置为永久的组件。不应该,但我以前在 MSI 上看到过这样的怪异。例如,我可以想象这对于永久部署到 System32 的组件集是必要的。总之:如果您只需要保留设置文件,只需使用次要升级将其设置为永久,然后您可以再次使用主要升级。不要将组件设置为可传递的。

顺便提一下:顺便说一下,您的设置文件实际上并没有被您当前的升级方案覆盖。主要升级期间将卸载并重新安装它,因为它的组件最初没有设置为Permanent = "yes"NeverOverwrite="yes"。这似乎已将其恢复为默认值,但从未被覆盖。而是将其卸载并重新安装以消除更改。 MSI 不会覆盖已更改的非版本控制文件,但它会很乐意卸载并重新安装它们,除非它们被标记为永久。在我看来,这是一种技术反模式——很多团队一直面临这个问题。因此,我建议查看此处所述的一些数据文件部署选项:Create folder and file on Current user profile, from Admin Profile(与上述相同的链接)。

我希望这对您有所帮助,请让我们知道您在测试期间发现了什么。


老答案

Brian 提到了真正的建议,但也许有一些问题需要澄清。一旦我得到一些答案,我会将其演变成一个尝试性的答案。

  • 这些自定义操作是如何运行的?它们是 EXE 命令还是您正在运行一个启动器 EXE 然后调用它们?如果您使用这样的启动器 EXE,它是本机 (C++) 还是 .NET? (C#/VB.NET)。如果是 .NET,那通常是个坏消息。
  • 我们能问一下你用这些复制命令做什么吗?这可以在应用程序本身中更可靠地完成吗?这可能是我们给人们最常见的建议,如果遵循这些建议,实际上可以大大简化部署并使其更加可靠。您可以更好地控制应用程序中发生的事情,在可预测的安全上下文中运行,并且无需处理任何条件或排序。最后:您可以重新启动应用程序并再次执行此操作,设置是“一次”。
  • 我将暂时保留它...

【讨论】:

  • 哇...谢谢您的详细解释。当我们将整个备份和恢复内容移动到一个 C# 自定义操作时,我们得到了这一切,现在该操作非常适合我们的安装程序。
【解决方案2】:

您应该更具体地说明“更新”的含义,因为它可能是补丁、次要升级、主要升级。如果这是一次重大升级,您应该说明它的排序位置。但是,可能会运行以前版本的自定义操作有两个一般原因:

  1. Brian 的评论/回答 - 它们在原始安装中的条件不正确,当更新通过旧安装中的序列时,它发现条件评估为 true。如果您愿意,没有安装自定义操作或卸载自定义操作之类的东西:只有带有条件的自定义操作。在作为更新发布的 WiX 源中,UPGRADINGPRODUCTCODE 的使用不正确。在重大升级期间卸载旧产品时会在旧产品中设置此属性,因此旧安装中的任何“或 UPGRADINGPRODUCTCODE”条件都将为真。如果您想要在升级旧产品时在升级安装中设置条件,请使用 MajorUpgrade 元素使用的 WIX_UPGRADE_DETECTED。

  2. 执行更新的行为导致了对旧产品的修复,因此它运行了自定义操作,它们甚至可能具有正确的条件。例如,如果一个二进制文件已被替换并且在您的更新期间是替换的候选者,则 Windows Installer 将修复并恢复不匹配的二进制文件,以便它可以决定是否从更新中安装该二进制文件。这将重新安装包含该二进制文件的功能。因此可以运行以功能或组件安装为条件的自定义操作。

此外,为了扩展 Stein 的回答,Windows Installer 和 WiX 有一个动作(请参阅 CopyFile 元素)。为什么将文件安装到一个位置并立即将其移动到另一个位置?我认为有理由不简单地安装它和最终位置而不做移动?

【讨论】:

  • 迁移的原因是我们在每次更新时都遇到了配置文件被覆盖的问题。因此,我们决定通过自定义操作(预安装)将它们复制到临时文件夹,并在安装后将其移回安装文件夹(安装后)。这将在每次更新时完成。到目前为止效果很好。我们唯一改变的是用 robocopy 替换 xcopy,现在在 udpate 上它仍然使用旧的自定义操作,即使日志文件显示“robocopy”,但仍然会创建 configfolders 中的旧文件名......我回到办公室了。到目前为止感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
相关资源
最近更新 更多