msi删除文件而不是替换它们

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了msi删除文件而不是替换它们相关的知识,希望对你有一定的参考价值。

我有一个.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就会在各个版本中保持稳定(它永远不会改变 - 如果它确实那么你需要一个新的组件GUID - 下面的解释)。

早期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自动组件GUID:If 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>

以上是关于msi删除文件而不是替换它们的主要内容,如果未能解决你的问题,请参考以下文章

在导航控制器上添加片段而不是替换片段?

使用导航架构组件添加(而不是替换)片段

根据字符串名称而不是列表视图项位置替换片段并启动活动

替换或删除后台堆栈上现有片段的代码不起作用

使用 zip 文件打包文件而不是 MSI

带有片段和 Jetpack 导航的 Viewpager2:恢复片段而不是重新创建它们