安装.exe文件时,请勿覆盖现有文件

时间:2018-02-06 07:05:01

标签: c# wix windows-installer

我已经安装了.exe应用程序(Say,Version 1.0)。安装应用程序后,我可以在本地路径(C:\ Program Files(x86))中看到几个DLL和几个.XML配置文件。现在,在踢完新版本并安装它之后,我不想在本地路径中单独覆盖现有的XML文件。有没有办法做到这一点?

我的EXE是使用WIX安装程序创建的,项目是在Visual Studio 2015中构建的。

3 个答案:

答案 0 :(得分:1)

您的申请如何运作?它是否会随着时间的推移将设置写入这些XML文件,您是否希望保留它们?如果是这样,他们存放在哪里?在每台机器或每用户位置?

让我试着为你描述一些你可能会遇到的问题 - 你无法提前预见(没有经过测试)。

有关文件覆盖的一些细节

  1. 文件版本控制规则 :MSI内置支持不覆盖自安装以来已修改的非版本化文件(创建和修改日期为不同)。这些是" File Versioning Rules"。它们有点复杂和奇怪 - 你一定要阅读链接的内容 - 真正的McCoy。因此,在更新期间不应更换已修改的非版本化文件 - 但有许多并发症和熊陷阱 - 并且大多数人似乎都属于其中一个。

  2. 主要升级文件还原 :也许是" 意外文件覆盖"中最常见的复杂功能根本不是覆盖。它涉及主要升级 - 或者如果您愿意,可以安装下一个产品版本。

    • 如果您使用主要升级来安装下一个版本,并在InstallExecuteSequence的早期安排RemoveExistingProducts,则实际上会卸载所有文件,然后以原始版本重新安装。它们似乎已被覆盖,但它们已经被卸载然后安装了#34; fresh"代替。

    • 这完全归功于MSI很乐意卸载修改后的文件,即使它们有资格不被覆盖也是如此。您需要的是一种定义文件根本不能卸载的方法。这将我们带到下一点:

  3. 永久和永不覆盖标志 :每个组件都有两个与文件覆盖和文件保存相关的重要设置:永不覆盖标志永久性旗帜。这确实是一种表明不应该替换或卸载文件的好方法。然而...

    • 仅设置永不覆盖标记对上述主要升级问题没有帮助,文件仍然会被卸载然后重新安装,因此它会被覆盖(但会被还原)。

    • 如果仅设置永久标志,则将根据文件版本规则覆盖该文件 - 前提是在命令行中未使用REINSTALLMODE等功能指定修改(请参阅下面的部分)。 (我需要再次验证这一点是100%肯定的。有很多因素:组件可以在较旧或较新的设置中永久设置 - 或者在两种设置中,主要升级可以提前或延迟卸载,REINSTALLMODE有很多味道等......每个变量都可以改变覆盖行为

    • 换句话说,建议设置永久和永不覆盖标志以保护设置文件。

  4. REINSTALLMODE :REINSTALLMODE是一个"修饰符"或File Overwrite / Versioning Rules的禁用者。可以在安装期间将REINSTALLMODE property设置为amus - 除其他外,这将强制覆盖安装期间的所有文件,无论上述文件版本规则如何。

    • amus REINSTALLMODE参数的说明:

      • a - 强制重新安装所有文件,无论版本如何
      • m - 重写所有转到HKLM或HKCU
      • 的注册表项
      • u - 重写所有转到HKCU或HKEY_USERS的注册表项
      • s - 重新安装快捷方式和图标
    • 有一天,我将用REINSTALLMODE及其实现来解决我的所有问题。它在MSI中是一个令人难以置信的破坏性概念,它永远不应该被使用。问题是这是一个通用命令行,可以传递给任何MSI包并适用于整个设置(为什么它至少不是每个功能?)。如果指定了amus,我想让我的包中止。

  5. 这是所有稍微疯狂是诚实的,但它的技术是如何工作的。所以,让我们停止抱怨并尝试解决问题。有什么方法可以解决这个问题?

    处理设置文件保存问题的一些选项

    总之,我认为你有几个选择:

    1. 使用次要升级升级您的应用 。然后,您的文件永远不会被卸载和重新安装,因此可以像重大升级一样恢复。

      • 次要升级不会卸载现有安装 - 它会直接升级。应用常规文件版本控制规则(不替换已修改的非版本化文件) - 除非使用REINSTALLMODE修改此逻辑。

      • 然而,很少有人通过轻微升级获得成功 - 他们限制性太强且有限。我会说,几乎没有。

    2. 在InstallExecuteSequence的早期使用RemoveExistingProducts进行重大升级,并为托管设置文件的组件使用永久性永不覆盖启用 。使用主要升级时,主要选择是旧版本的早期和晚期卸载,这种选择具有重大意义。

      • 此部分需要进行一些清理。很快就会发生。

      • 提前卸载意味着任何引用错误的组件都不会导致任何问题。他们更加宽容"如果你喜欢。很多人最终都使用这种方法,因为这是最宽容的#34;组件引用错误和整体"健壮性"。

      • 提前卸载还意味着可以在升级过程中卸载并重新安装已修改的文件,导致它们被覆盖,但会被还原(如上所述)。

      • 解决上述问题的方法是将文件的托管组件设置为永久永不覆盖

      • 提前卸载意味着可以破坏复杂的组件创建规则,您的升级仍然有效。破坏组件创建规则是很常见的。如果使用此方法,则应将升级期间要保留的文件设置为永久性,并且永远不会覆盖。这样可以防止卸载修改后的文件并安装新文件的问题 - 让人觉得文件已被覆盖。

    3. 使用InstallExecuteSequence 后期的RemoveExistingProducts进行重大升级。

      • 延迟卸载主要升级安装不会卸载并重新安装旧设置和新设置中位于同一位置的文件 - 即使有问题的文件未设置为永久性且永不覆盖(允许正确)卸载文件 - 没有任何添加的自定义逻辑。)

      • 这种升级基本上安装为"补丁" - 保持版本之间未更改的文件不变,然后根据上述文件版本控制规则升级其他文件。

      • 相反,它们将根据正常的文件版本控制规则进行覆盖(前提是您未将REINSTALLMODE设置为等于amus - 在这种情况下,您将降级所有内容并清除设置)。

      • 上一个回答:How to keep a config file when major upgrade in wix v3.8?

    4. 设置文件的自定义备份机制 :许多人最终会实施复杂的自定义操作来备份设置文件,并在安装运行后将其重新放回原位

      • 我不喜欢这种方法,因为它可能会导致自定义操作失败,但很多人都使用此选项。通常,这是在应用程序的第2版中添加的功能,因为所讨论的文件未被设置为永久性且"永远不会覆盖"在版本1的设置中。

      • 为此类自定义操作获取排序模拟(您运行的用户/系统上下文)和条件权限<强大>一点也不琐事。

      • 作为所涉及的复杂性的一个具体例子,这里是一个先前的问题/答案,其中已经实现了这样一个特征,并且确定究竟发生了什么有问题:Wix Tools update uses old custom actions

        • 正在进行非常复杂的调节,以便在不同的安装模式(新安装,升级,维修,修改等等)的正确时间进行备份和恢复操作。
    5. 消除部署中的设置文件 :这是我最喜欢的选项,虽然听起来有点奇怪。任何可以使你的设置&#34; dumber&#34;而且不那么复杂会使它在实际使用中更加可靠。

      • 基本上安装后要更改的文件根本不应安装,而是由应用程序生成或从模板文件复制到要更改的位置。

        • 在这些情况下,任何部署问题都不会干扰您宝贵的设置文件 - 除非您做出奇怪的自定义操作(您不应该这样做)。

        • 您的设置不知道这些设置文件是否存在,因此它们将始终保持不变。这通常是你想要的。

        • 您可以制作自己的清理功能,以便在卸载时将其删除,不过我的建议是不要管它们:它们是用户数据。

      • 我在这个答案中写了与每个用户和设置文件部署相关的一般问题: Create folder and file on Current user profile, from Admin Profile 。请至少快速浏览,看看是否可以通过消除复杂性来改善部署,而不是接受它。

        • 基本上,有多种方法可以在设置中部署设置和用户文件( Active Setup 自我修复等等。)

        • 然后有模板文件,您可以&#34;实例化&#34;并且不要使用你的设置(如上所述没有干扰)。

        • 在某些情况下,您可以使用应用程序内部默认值而不是设置文件 - 消除所有部署注意事项。

        • 最后,您可以从网络(数据库)检索设置,而不是使用旧式设置文件。

答案 1 :(得分:0)

您可以做的一件事是阻止安装程序卸载上一个版本。您可以为配置文件添加NeverOverwrite属性。

我找到了这个解决方案here

答案 2 :(得分:0)

假设您正在进行重大升级,有两种常规解决方案:

如果您的升级安排为“延迟”,例如afterInstallExecute,则升级安装在旧产品的“上方”,因此文件覆盖规则已经过时。对于数据文件,这意味着如果文件在安装后已更新(修改日期&gt;创建日期),则不会覆盖该文件:

Neither File Has a Version

换句话说,升级只会起作用,您根本不需要做任何事情。

如果您的升级是“早期”安排的,例如afterInitinalize,则实际上是卸载后安装,因此您将在卸载时丢失该文件。在这些情况下,通常最好在升级之前(在RemoveExistingProducts之前)使用自定义操作将文件复制到安全位置,然后在升级中将其还原。或者让应用程序将实际数据保存在与安装中的文件不同的副本文件中,因此安装中的文件是“模板”而不是实际的模板。