【问题标题】:msi removing files instead of replacing themmsi 删除文件而不是替换它们
【发布时间】:2018-08-27 21:53:39
【问题描述】:

我有一个 .msi 安装程序,可以放置多个文件。版本更新后,文件获得了新的 GUID,现在当从版本 1 更新到 2 时,安装程​​序会删除其中一些文件而不是更新它们。

查看它为具有新 ID 的文件调用注册组件的日志,但有一条消息我怀疑可能是原因:

File: <PATH_TO_FILE>; Overwrite; Won't patch; Existing file is unversioned and unmodified - hash doesn't match source file

如何确保将具有新 GUID 的文件复制到旧版本之上(使其版本化)?

更新:

我尝试将ReinstallMode 设置为“amus”,而不是“omus”,但似乎因为以前的 .msi 是“omus”,文件仍然消失,除非我连续运行两次新安装程序,这不是最优的。

基本上我需要一个版本 3 安装程序,它可以升级版本 1 或 2 并且不删除有问题的文件(如果可能的话)

【问题讨论】:

  • 你用的是什么工具?维克斯?本质上,您需要在版本之间保持组件 GUID 稳定。您可以使用 WiX 的自动 GUID 来执行此操作(自动生成的 GUID)。您还必须断开与过去罪恶的链接,因此我建议设置一个新的主安装路径。这将起作用,但您必须确定它是否适合您的产品。它有多大?您是否有必须在新版本中保留的设置文件?
  • @Stein Åsmul 很遗憾无法更改安装位置和 GUID。改回 GUID 只会在版本 2 和 3 之间产生同样的问题
  • 我能问一下RemoveExistingProducts 在您最终编译的MSI 中的InstallExecuteSequence 中的什么位置吗?在 Orca 中打开,查看InstallExecuteSequence 表,按Sequence column 排序。 RemoveExistingProducts 之前的动作是什么? (以及序号是多少)。
  • @Stein Åsmul 在RemoveExistingProducts (6601) 之前是InstallFinalize (6600)

标签: windows-installer


【解决方案1】:

快速修复:我已在顶部添加了此摘要部分,但也请阅读以下详细信息部分。您遇到了常见问题 搞砸了组件引用计数,这是 导致您看到的这些升级问题。组件 GUID 将 只要关键路径不改变,跨版本保持稳定 (它永远不应该改变 - 如果它改变了,那么你需要一个新组件 GUID - 解释如下)。

Early REP:与其解决真正的问题,不如用一种不太理想的方法来处理它,那就是使用 我们称之为“Early REP”。本质上你移动 RemoveExistingProducts 位于 InstallExecuteSequence 之前,位于 InstallInitialize 之前。这将完全卸载旧的 版本,然后安装新版本及其所有文件(通常)- 不受干扰。您将新版本与过去的罪恶解耦。这可以使用Orca or an equivalent free tool(底部)来修复您的 已编译的 MSI(更改 InstallExecuteSequence 表中的序列号)或者可以在您的源文件中完成 - 无论哪种工具 你正在使用。


组件引用计数:错误的组件 GUID 以及因此 MSI 组件的引用计数是一件非常糟糕的事情 - 不得不说。 The component / key path concept 是 MSI 本身的核心——它如何处理文件更新和维护以及引用计数。 The concept is essentially that for every absolute key-path there is supposed to be a single component GUID, shared by all packages targeting that location。这里有更多细节:Change my component GUID in wix?

WiX 自动组件 GUIDIf you are using WiX(我们不知道你是否这样做),那么我建议您使用 WiX's auto-GUID concept 组件 GUID 是根据安装密钥路径计算的,而不是在 WiX 源代码中硬编码(或由构建过程生成)。此 WiX 算法将以“自动魔术”方式处理引用计数。

此答案试图解释 WiX 自动组件 GUID 背后的基本原理以及它如何使您受益:Syntax for guids in WIX? 并非所有安装位置都允许自动生成组件 GUID,但大多数情况下部分它是一个全面的“自动魔法”。

代码示例:使用自动组件 GUID 时,您无需在源代码中指定 GUID:

<!-- Sample guid below, do not copy paste -->
<Component Id="File.dll" Guid="{12345678-1234-1234-1234-123456789ABC}">
  <File Id="File.dll" Name="File.dll" KeyPath="yes" Source="..\File.dll" />
</Component>

与自动组件 GUID:

<Component>
  <File Source="..\File.dll" />
</Component>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    相关资源
    最近更新 更多