我已经安装了 .exe 应用程序(例如版本 1.0)。安装应用程序后,我可以在本地路径(C:\Program Files (x86))中看到几个 DLL 和几个 .XML 配置文件。现在,在启动新版本并安装它之后,我不想单独覆盖本地路径中的现有 XML 文件。有什么办法可以做到吗?
我的 EXE 是使用 WIX 安装程序创建的,项目是在 Visual Studio 2015 中构建的。
您的应用程序如何运作?随着时间的推移,它是否会将设置写入这些 XML 文件,因此您想要保留它们?如果是,它们存储在哪里?在每台机器或每用户位置?
让我尝试为您描述一些您可能会遇到的问题 - 您不可能提前预见(未经测试)。
文件版本控制规则:MSI 具有内置支持,不会覆盖自安装以来已修改的非版本控制文件(创建和修改日期不同)。这些是“文件版本控制规则”。它们有些复杂和奇怪 -你一定应该阅读链接的内容- 真正的麦考伊。因此,修改后的非版本化文件不应在更新期间被替换 - 但这会带来许多并发症和陷阱- 大多数人似乎都会陷入其中之一。
主要升级文件恢复:也许“意外文件覆盖”最常见的并发症根本不是覆盖。它涉及重大升级- 或者安装您的下一个产品版本(如果您愿意)。
如果您使用主要升级来安装下一个版本,并且您在 InstallExecuteSequence 的早期安排了 RemoveExistingProducts,则所有文件实际上都会被卸载,然后重新安装为其原始版本。它们似乎已被覆盖,但它们已被卸载,然后“全新”安装。
这都是由于一个非常奇怪的决定,MSI 会很乐意卸载修改过的文件,即使它们符合不被覆盖的条件。您需要的是一种方法来定义根本不卸载的文件。这让我们想到了下一点:
永久和永不覆盖标志:每个组件都有两个与文件覆盖和文件保存相关的重要设置:永不覆盖标志和永久标志。这确实是指示文件不应被替换或卸载的好方法。然而...
仅设置永不覆盖标志无助于解决上述主要升级问题,该文件仍会被卸载然后重新安装,因此它看起来被覆盖(但已恢复)。
如果仅设置永久标志,则文件将根据文件版本规则被覆盖 - 前提是未使用 REINSTALLMODE 等功能在命令行指定修改(请参阅下面的部分)。(我需要再次验证这一点以确保 100% 确定。有很多因素:组件只能在较旧或较新的设置中永久设置 - 或在两种设置中,主要升级可以提前或延迟卸载,REINSTALLMODE 有多种风格,等等...每个变量都可以改变覆盖行为)
换句话说,建议设置永久标志和永不覆盖标志来保护设置文件。
REINSTALLMODE :REINSTALLMODE 是文件覆盖/版本控制规则( symantec )的“修改器”或禁用器。可以在安装期间将REINSTALLMODE 属性设置为等于amus- ,这将(除其他外)在安装期间强制覆盖所有文件,而不管上述文件版本规则如何。
amus REINSTALLMODE参数说明:
a- 强制重新安装所有文件,无论版本如何m- 重写所有进入 HKLM 或 HKCU 的注册表项u- 重写所有指向 HKCU 或 HKEY_USERS 的注册表项s- 重新安装快捷方式和图标这些天我会写一篇关于 REINSTALLMODE 及其实现的问题。在 MSI 中,这是一个极具破坏性的概念,永远不应该使用它。问题是这是一个通用命令行,可以传递到任何 MSI 包并适用于整个设置(为什么不能至少针对每个功能?)。如果指定的话,我想让我的包中止amus。让我快速记下一些问题:
m和 的u开关amus将完全重置由组件(而不是自定义操作代码)写入的注册表数据,而与a开关无关(至少我上次尝试时是这种情况)。在我的MSI 反模式列表中名列前茅(请参阅“潜在反模式”部分)。GAC,WinSxS. 我什至不知道 GAC 是如何运作的?并排设计是不可降级的吗?有人会想。除非您直接在程序集文件夹中查找 - 这希望会触发运行时错误 - 我还没有尝试过。事实上我认为不会。请参阅发布者配置文件的此问题(请参阅“线程”中的所有推文)。说实话,这有点疯狂,但这就是技术的工作原理。所以,让我们停止抱怨并尝试解决问题。有哪些选项可以解决这个问题?
总而言之,我想你有几个选择:
使用小升级来升级您的应用程序。这样您的文件就永远不会被卸载和重新安装,因此会像重大升级一样被恢复。
次要升级不会卸载现有安装 - 它会直接升级。常规文件版本控制规则适用(修改后的非版本控制文件不会被替换) - 除非使用 REINSTALLMODE 来修改此逻辑。
然而,很少有人仅通过较小的升级就能成功——它们的限制太多。我想说几乎没有。
在 InstallExecuteSequence 的早期阶段使用 RemoveExistingProducts 进行重大升级,并为托管设置文件的组件启用永久且永不覆盖的功能。当使用重大升级时,主要选择是早期卸载旧版本和后期卸载旧版本,这种选择具有巨大的影响。
这部分需要一些清理。很快就会发生...... 2019 年 12 月:我们回来了。多年后。今天进行了一些小清理工作 - 没有什么其他的。我将继续承诺进一步清理此事。空洞的承诺让世界变得团团转。如果这一切看起来像是在抱怨,请阅读 MSI 的主要优点(快速列表)。MSI 对以前的部署技术进行了至关重要的改进,但仍面临一些重大挑战。
提前卸载意味着您所犯的任何引用错误的组件都不会导致任何问题。如果你愿意的话,他们会更“宽容”。很多人最终特别使用这种方法,因为它对组件引用错误和整体“稳健性”最“宽容”。
提前卸载还意味着可以在升级过程中卸载并重新安装修改的文件,导致它们看起来被覆盖,但它们会被还原(如上所述)。
解决上述问题的方法是将文件的托管组件设置为永久且永不覆盖。
提前卸载意味着可以打破复杂的组件创建规则,并且您的升级仍然有效。违反组件创建规则是很常见的。如果您使用这种方法,您应该将升级期间要保留的文件设置为永久,并且也不要覆盖。这应该可以防止出现修改后的文件被卸载并安装新文件的问题 - 产生文件已被覆盖的印象。
在InstallExecuteSequence 后期使用RemoveExistingProducts 进行重大升级。
后期卸载主要升级安装不会卸载并重新安装旧设置和新设置中同一位置中存在的文件 - 即使有问题的文件未设置为永久且从不覆盖(也允许正确卸载文件),这仍然有效- 没有任何添加的自定义逻辑)。
这种升级基本上作为“补丁”安装 - 保持版本之间未更改的文件不变,然后根据上述文件版本控制规则升级其他文件。
相反,它们将根据正常的文件版本控制规则被覆盖(前提是您没有将 REINSTALLMODE 设置为 amus - 在这种情况下,您会降级所有内容并清除设置)。
上一个答案:wix v3.8重大升级时如何保留配置文件?。
设置文件的自定义备份机制:许多最终会实现复杂的自定义操作,备份设置文件并在安装运行后将它们放回原位。
我不喜欢这种方法,因为它可能会导致自定义操作失败,但许多人都使用此选项。通常,这是应用程序版本 2 中添加的一项功能,因为相关文件未在版本 1 的设置中设置为永久且“永不覆盖”。
为此类自定义操作获得正确的排序、模拟(您运行的用户/系统上下文)和条件并非易事。
作为所涉及的复杂性的具体示例,这里是之前的问题/答案,其中已经实现了此类功能,并且存在确定到底发生了什么的问题:Wix Tools update using old custom actions。
复杂性:需要进行非常复杂的调节,以使备份和恢复操作在不同的安装模式(全新安装、升级、修复、修改等)中适时发生。
条件调试器 Light (practical tip!):为了计算出复杂的条件,我喜欢对条件进行非常具体的实际测试,而不是进行过多的分析(是的,无论如何你都会失败 - 不知何故)。
这是我使用的总体方法:VBScript 条件测试器。它本质上是来自受条件自定义操作的对话框方法 - 它在现实生活中显示自定义操作何时运行,而无需任何日志记录或复杂的调试。
只需在不同模式下运行安装程序,然后查看是否看到对话框:install, uninstall, modify,
repair, patching, major upgrade, suspended-resume...
从部署中消除设置文件:这是我最喜欢的选项,尽管听起来有点奇怪。任何可以使您的设置变得“更愚蠢”且不那么复杂的东西都将使其在实际使用中更加可靠。
本质上,安装后要更改的文件根本不应该安装,而是由应用程序生成或从模板文件复制到要更改的位置。
在这些情况下,任何部署问题都不会干扰您宝贵的设置文件 - 除非您执行一个奇怪的自定义操作来执行此操作(您不应该这样做)。
您的设置不知道这些设置文件的存在,因此它们将始终保持不变。这通常是您想要的。
您可以创建自己的清理功能以在卸载时删除它们,尽管我的建议是不要理会它们:它们是用户数据。
我在这个答案中写了与每用户和设置文件部署相关的一般问题:在当前用户配置文件上从管理配置文件创建文件夹和文件。请至少快速浏览一下,看看是否可以通过消除复杂性而不是拥抱复杂性来改进部署。
本质上,有多种方法可以在安装程序中部署设置和用户文件(主动安装、自我修复等)。
然后是您可以“实例化”并保留在您的设置之外的模板文件(如上所述,不会产生干扰)。
在某些情况下,您可以使用应用程序内部默认值而不是设置文件 - 消除所有部署注意事项。
最后,您可以从网络(数据库)检索设置,而不是使用旧式设置文件。
实用建议:如果可以的话,请使用数据库作为您的设置或某种形式的云方法来从您的设置中获取设置文件。仅部署您的二进制文件!以及在启动时创建设置文件或注册表设置所需的模板。这将极大地帮助简化您的设置。
链接:
| 归档时间: |
|
| 查看次数: |
3450 次 |
| 最近记录: |