我们安装 .exe 文件时不要覆盖现有文件

编程入门 行业动态 更新时间:2024-10-25 18:31:11
本文介绍了我们安装 .exe 文件时不要覆盖现有文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已经安装了 .exe 应用程序(比如说,1.0 版).安装应用程序后,我可以在本地路径(C:Program Files (x86))中看到几个 DLL 和几个 .XML 配置文件.现在,在启动新版本并安装它之后,我不想在我的本地路径中单独覆盖现有的 XML 文件.有什么办法吗?

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

解决方案

您的应用程序是如何工作的?它是否会随着时间的推移将设置写入这些 XML 文件,因此您想要保留它们?如果是这样,它们存储在哪里?在每台机器或每用户位置?

让我尝试为您描述一些您可能会面临的问题 - 您可能无法提前预见(未经测试).

关于文件覆盖的一些细节

  • 文件版本控制规则:MSI 内置支持不覆盖自安装以来已修改的非版本控制文件(创建和修改日期为不同的).这些是文件版本控制规则".它们有些复杂和奇怪 - 您一定要阅读链接内容 - 真正的 McCoy.因此,在更新期间不应替换修改过的非版本化文件 - 但有许多复杂性和陷阱 - 大多数人似乎都陷入其中之一.

  • 重大升级文件还原:也许意外文件覆盖"最常见的并发症根本不是覆盖.它与重大升级有关 - 或者如果您愿意,可以安装您的下一个产品版本.

    • 如果您使用主要升级来安装您的下一个版本,并且您在 InstallExecuteSequence 的早期安排了 RemoveExistingProducts,那么实际上所有文件都将被卸载,然后在其原始版本中重新安装.它们似乎已被覆盖,但它们已被卸载,然后改为全新"安装.

    • 这完全是因为 MSI 会愉快地卸载修改过的文件,即使它们有资格不被覆盖.您需要一种方法来定义根本不卸载的文件.这将我们带到下一点:

  • 永久和永不覆盖标志:每个组件都有两个与文件覆盖和文件保存相关的重要设置:永不覆盖标志 和永久旗帜.这确实是指示文件不应被替换或卸载的好方法.不过……

    • 仅设置永不覆盖标志无助于解决上述主要升级问题,该文件仍会被卸载然后重新安装,因此它看起来已被覆盖(但已恢复).

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

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

  • REINSTALLMODE:REINSTALLMODE 是 文件覆盖/版本控制规则 (赛门铁克).可以设置 安装期间的 REINSTALLMODE 属性 等于 amus - 这将(除其他外)在安装期间强制覆盖所有文件,无论上述文件版本规则如何.

    • amus的解释REINSTALLMODE 参数:

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

      • 降级:可以在系统范围内降级共享文件.这些文件可以来自合并模块,因此人们可能没有意识到他们以系统文件夹为目标.Windows 10 现在可以很好地保护其操作系统文件,但仍有其他文件可以在没有操作系统保护的情况下降级.
      • 版本不一致:可能会导致版本不一致,因为旧包可以在新包之后安装,并且只能降级某些共享文件.
      • 设置清除:可以降级或清除非版本控制文件(和注册表设置)中的设置.
      • 重启提示:由于尝试不必要地替换相同版本的正在使用的文件,可能会导致请求重启的次数显着增加.有一些功能可以避免这种情况,但它们通常没有正确使用.重启管理器,更多重启经理.
      • 还有更多...:还有几个非常具体的问题.总有一天我会把它们都写下来.我认为.也许不会?:-).
        • Windows 文件保护 (WFP):也许我可以补充一点,某些旧合并模块包含现在受操作系统保护的文件,并尝试替换它们 用于可能触发运行时错误.这现在由 Windows 10 静默"处理.
        • Registry:m 和 u> amus 的开关将彻底重置组件(而不是自定义操作代码)写入的注册表数据,而与 a switch(至少我上次尝试时是这样).我的 MSI 反模式列表(参见潜在的反模式"部分).
        • 未知数:GAC、WinSxS.我什至不知道 GAC 是如何运作的?并排设计是不可降级的吗?有人会想.除非您直接在程序集文件夹内四处寻找 - 希望这会触发运行时错误 - 我没有尝试过.事实上,我认为不会.查看此问题与 发布者配置文件(查看线程"中的所有推文).
  • 说实话,这有点疯狂,但这就是技术的运作方式.所以,让我们停止抱怨并尝试解决问题.有什么办法可以解决这个问题?

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

    总的来说,我想你有几个选择:

  • 使用小升级来升级您的应用程序.然后,您的文件永远不会被卸载和重新安装,因此会像进行重大升级一样被还原.

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

    • 然而,很少有人只通过小幅升级就能成功 - 他们过于严格和受限.我想说的几乎没有.

  • 在 InstallExecuteSequence 早期使用 RemoveExistingProducts 进行重大升级,并为托管设置文件的组件启用永久且永不覆盖.使用重大升级时,主要选择是提前卸载旧版本还是延迟卸载旧版本,这种选择具有巨大的影响.

    • 这部分需要清理一下.很快就会发生......2019 年 12 月:我们回来了.多年后.今天发生了一些小的清理工作——其他的不多.我将继续承诺会更多地清理它.空洞的承诺使世界转转.如果这一切似乎都在抱怨,请阅读 MSI 的主要优势(快速列表).MSI 对以前的部署技术进行了至关重要的改进,但还存在一些重大挑战.

    • 提前卸载意味着您​​所做的任何组件引用错误都不会导致任何问题.如果你愿意,他们会更宽容".很多人最终都使用这种方法,因为它最宽容"了组件引用错误和整体健壮性".

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

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

    • 提前卸载意味着可以打破复杂的组件创建规则,您的升级仍然可以工作.破坏组件创建规则是很常见的.如果您使用这种方法,您应该将升级期间要保留的文件设置为永久文件,并且永远不要覆盖.这应该可以防止修改文件被卸载并安装新文件的问题 - 产生文件已被覆盖的印象.

  • 在 InstallExecuteSequence 后期使用 RemoveExistingProducts 进行重大升级.

    • 后期卸载主要升级安装不会卸载和重新安装旧设置和新设置中存在于同一位置的文件 - 即使相关文件未设置为永久且永不覆盖(允许适当的也可以卸载文件 - 不添加任何自定义逻辑).

    • 这种升级基本上是作为补丁"安装的——在不同版本之间保持不变的文件保持不变,然后根据上述文件版本控制规则升级其他文件.

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

    • 上一个答案:wix v3.8重大升级时如何保留配置文件?.

  • 设置文件的自定义备份机制:许多最终实施复杂的自定义操作,备份设置文件并在安装运行后将它们放回原位.

    • 我不喜欢这种方法,因为它可能会导致自定义操作失败,但许多人使用此选项.这通常是应用程序版本 2 中添加的一项功能,因为相关文件在版本 1 的设置中并未设置为永久且永不覆盖".

    • 为此类自定义操作获取 排序、模拟(您在其中运行的用户/系统上下文)和 调节 是 一点都不简单.

    • 作为所涉及的复杂性的具体示例,这里是以前的问题/答案,其中已经实现了这样的功能,并且在确定到底发生了什么时存在问题:Wix 工具更新使用旧的自定义操作.

      • 复杂性:为了使备份和恢复操作在不同的安装模式(全新安装、升级、维修、修改等)

      • Condition Debugger Light(实用技巧!):为了解决复杂的条件,我喜欢非常具体地对条件进行实际测试,而不是进行过多的分析(是的,无论如何你都会失败 - 不知何故).

        • 这是我使用的总体方法:VBScript 条件测试器.它本质上是一种来自受条件自定义操作的对话框方法 - 它在现实生活中显示自定义操作何时运行而无需任何日志记录或复杂调试.

        • 只需在不同模式下运行安装程序,看看是否看到对话框:install、uninstall、修改、repair、patching、重大升级、suspended-resume...

  • 从部署中删除设置文件:这是我最喜欢的选项,虽然听起来有点奇怪.任何可以使您的设置笨拙"且不那么复杂的东西都会使其在实际使用中更加可靠.

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

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

      • 您的设置不知道这些设置文件的存在,因此它们将始终不存在.这通常是您想要的.

      • 您可以使用自己的清理功能在卸载时删除它们,但我的建议是不要管它们:它们是用户数据.

    • 我在这个答案中写了与每个用户和设置文件部署相关的一般问题:从管理员配置文件中创建当前用户配置文件的文件夹和文件.请至少快速浏览一下,看看您是否可以通过消除复杂性而不是接受它来改进您的部署.

      • 基本上有多种方法可以在设置中部署设置和用户文件(Active Setup、self-repair 等...).p>

      • 然后有模板文件,您可以实例化"它们并远离您的设置(如上所述没有干扰).

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

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

  • 实用建议:如果可以,请使用数据库进行设置或某种形式的云方法从设置中获取设置文件.部署你的仅限二进制!以及在启动时进行设置文件或注册表设置所需的模板.这将极大地简化您的设置.

    链接:

    • 另一面:文件未正确覆盖

    I have installed the .exe application (Say, Version 1.0). After installing the application, I can see several DLL's and few .XML config files in my local path(C:Program Files (x86)). Now after kicking the new build and installing it I do not want to override the existing XML file alone in my local path. Is there any way to do it?

    My EXE is created using WIX installer and the project is built in Visual Studio 2015.

    解决方案

    How does your application work? Does it write settings to these XML files over time, and you hence want to preserve them? If so, where are they stored? In a per-machine or per-user location?

    Let me try to describe some problems for you that you are likely to face - and you could not possibly foresee ahead of time (without testing).

    Some details about file overwriting

  • File versioning rules: MSI has built-in support to not overwrite non-versioned files that have been modified since installation (the create and modify dates are different). These are "File Versioning Rules". They are somewhat complicated and strange - you should definitely read the linked content - the real McCoy. So modified non-versioned files should not be replaced during updates - but there are many complications and bear-traps - and most people seem to fall into one of them.

  • Major upgrade file reversion: Perhaps the most common complication seen for "unexpected file overwrite" is not an overwrite at all. It relates to major upgrades - or installing your next product version if you like.

    • If you use a major upgrade to install your next version, and you schedule RemoveExistingProducts early in the InstallExecuteSequence, then all files are actually uninstalled and then reinstalled in their original version. They will appear to have been overwritten, but they have been uninstalled and then installed "fresh" instead.

    • This is all due to the very strange decision that MSI will happily uninstall modified files, even if they qualify to not be overwritten. What you need is a way to define the files to not be uninstalled at all. Which brings us to the next point:

  • Permanent and Never Overwrite Flags: Each component has two important settings relating to file overwrite and file preservation: the never overwrite flag and the permanent flag. This is indeed a good way to indicate that a file should not ever be replaced, nor uninstalled. However...

    • Setting only the never overwrite flag will not help against the major upgrade problem described above, the file is still uninstalled and then reinstalled so it appears overwritten (but is reverted).

    • If you set the permanent flag only, the file will be overwritten according to the File Version Rules - provided no modification is specified at the command line using features such as REINSTALLMODE (see section below). (I will need to verify this again to be 100% sure. There are many factors: component can be set permanent in older or newer setup only - or in both setups, major upgrade can uninstall early or late, REINSTALLMODE has many flavours, etc... Each variable can change the overwrite behavior)

    • In other words setting both the permanent and never overwrite flags is recommended to protect settings files.

  • REINSTALLMODE: REINSTALLMODE is a "modifier" or disabler of the File Overwrite / Versioning Rules (symantec). It is possible to set the REINSTALLMODE property during installation equal to amus - which will (among other things) force overwrite all files during installation regardless of the above mentioned file version rules.

    • Explanation of the amus REINSTALLMODE parameters:

      • a - Force all files to be reinstalled, regardless of version
      • m - Rewrite all registry keys that go to HKLM or HKCU
      • u - Rewrite all registry keys that go to HKCU or HKEY_USERS
      • s - Reinstall shortcuts and icons
    • One of these days I will write up issues with REINSTALLMODE and its implementation. It is an incredibly destructive concept in MSI, and it should never, ever be used. The problem is that this is a generic command line that can be passed to any MSI package and applies for the whole setup (why couldn't it at least be per feature?). I want to make my packages abort if amus is specified. Let me jot down quickly a few of the issues:

      • Downgrade: Can downgrade shared files system-wide. The files can come from merge-modules so people might not realize they target system folders. Windows 10 protects its OS-files pretty well now, but there are other files that can still be downgraded without OS-protection.
      • Inconsistent Versions: Can cause inconsistent version estate since an old package can be installed after a newer one and downgrade only some of the shared files.
      • Settings Wipe-out: Can downgrade or wipe-out settings in non-versioned files (and registry settings).
      • Reboot Prompts: Can cause a significant increase in the number of requested reboots due to attempts to needlessly replace in-use files of the same version. There are features to avoid this, but they are often not used correctly. Restart Manager, more on restart manager.
      • And then there was more...: There are several further issues that are quite specific. One day I will write them all up. I think. Maybe not? :-).
        • Windows File Protection (WFP): Maybe I can add that certain legacy merge modules contain files that are now protected by the OS, and trying to replace them used to potentially trigger a runtime error. This is now handled by Windows 10 "silently".
        • Registry: The m and u switches of amus will reset registry data written by components (and not custom action code) outright irrespective of the a switch (At least this was the case last time I tried). High on my MSI anti-pattern list (see section "Potential Anti-Patterns").
        • Unknowns : GAC, WinSxS. I don't even known how things work with the GAC? Side-by-side is un-downgradable by design? One would think. Unless you poke around inside the assembly folder directly - which hopefully will trigger a runtime error - which I have not tried. In fact I don't think it will. See this issue with publisher configuration files (see all tweets in "thread").
  • This is all slightly mad to be honest, but it is how the technology works. So, let us stop complaining and try to deal with the problem. What are the options to deal with this?

    Some options to deal with settings file-preservation issues

    In summary I suppose you have a couple of options:

  • Use minor upgrades to upgrade your application. Then your files are never prone to be uninstalled and reinstalled and hence be reverted like they are for major upgrades.

    • A minor upgrade does not uninstall the existing installation - it upgrades it directly. Regular file versioning rules apply (modified non-versioned files are not replaced) - unless REINSTALLMODE is used to modify this logic.

    • However, few people succeed with minor upgrades only - they are too restrictive and limited. Close to none I would say.

  • Use a major upgrade with RemoveExistingProducts early in the InstallExecuteSequence and permanent and never overwrite enabled for the components hosting your settings files. When using a major upgrade the main choice is between early and late uninstall of the old version, and this choice has huge implications.

    • This section needs some cleanup. Will happen soon.... December 2019: and we are back. Years later. Some minor cleanup happened today - not much else. I shall keep promising to clean this up more. Empty promises makes the world go round and round. If this all seems like complaining, please read the major benefits of MSI (quick list). MSI delivered crucially important improvements to previous deployment technologies, but has a few big challenges left.

    • Early uninstall means that any component referencing errors you have made shouldn't cause any problems. They are more "forgiving" if you like. A lot of people end up using this approach specifically because is the most "forgiving" of component referencing errors and overall "robustness".

    • Early uninstall also means that modified files can be uninstalled and reinstalled during the upgrade, causing them to appear overwritten, but they are reverted (described above).

    • A remedy for the above problem is to set the hosting components for files to be permanent and never overwrite.

    • Early uninstall means that the complex component creation rules can be broken and your upgrade will still work. It is very common to break the component creation rules. If you use this approach you should set the files you want to preserve during upgrades to permanent and throw in never overwrite too. This should prevent the problem where modified files get uninstalled and fresh files are installed - yielding the impression that the files have been overwritten.

  • Use a major upgrade with RemoveExistingProducts late in the InstallExecuteSequence.

    • Late uninstall major upgrade installations do not uninstall and reinstall files that exist in the same location in the old and the new setups - and this works even when the files in question are not set permanent and never overwrite (allowing proper uninstall of the files as well - without any added, custom logic).

    • This kind of upgrade basically install as a "patch" - leaving files that are unchanged between releases untouched, and then upgrading other files according to the File Versioning Rules described above.

    • Rather they will be overwritten based on the normal file versioning rules (provided you did not set the REINSTALLMODE equal to amus - in which case you downgrade everything and wipe out settings).

    • Previous answer: How to keep a config file when major upgrade in wix v3.8?.

  • Custom backup mechanisms for settings files: many end up implementing complex custom actions that back up settings files and put them back in place after the installation has run.

    • I don't like this approach due to its potential for custom action failures, but many use this option. Often this is a feature added in version 2 of an application since the files in question were not set permanent and "never overwrite" in the setup for version 1.

    • Getting the sequencing, impersonation (user / system context you run in) and conditioning right for such custom actions is not at all trivial.

    • As a concrete example of the complexities involved, here is a previous question / answer where such a feature has been implemented and there are problems determining exactly what is going on: Wix Tools update uses old custom actions.

      • Complexity: Very complex conditioning is going on to make the backup and restore operations happen at the right time in different installation modes (fresh install, upgrade, repair, modify, etc...)

      • Condition Debugger Light (practical tip!): To work out the complicated conditions I like to go very concrete with real-world testing of the conditions instead of too much analysis (yes, you will fail anyway - somehow).

        • Here is the overall approach I use: VBScript condition tester. It is in essence a dialog box approach from a custom action that is conditioned - it shows in real life WHEN the custom action runs without any logging or complex debugging.

        • Just run the setup in different modes and see if you see the dialog: install, uninstall, modify, repair, patching, major upgrade, suspended-resume...

  • Eliminate settings files from deployment: this is my favorite option, although it may sound a bit strange. Anything that can make your setup "dumber" and less complex will make it more reliable in actual use.

    • Essentially files that are to be changed after installation should not be installed at all, but generated by the application or copied from template files to the location where they are to be changed.

      • In these scenarios no deployment issues will ever interfere with your precious settings files - unless you make a weird custom action to do so (which you shouldn't).

      • Your setup has no knowledge that these settings files exist, and they will hence always be left alone. Which is very often what you want.

      • You can make your own cleanup feature to delete them on uninstall, although my advice would be to leave them alone: they are user data.

    • I write about the general problems related to per-user and settings file deployment in this answer: Create folder and file on Current user profile, from Admin Profile. Please have a quick skim at least, to see if you can improve your deployment by killing complexity rather than embracing it.

      • Essentially there are various ways to deploy settings and user files in a setup (Active Setup, self-repair, etc...).

      • Then there are template files that you can "instantiate" and keep out of your setups (no interference as described above).

      • You can use application internal defaults instead of settings files in some cases - eliminating all deployment considerations.

      • And finally you can retrieve settings from the network (database) instead of using old-style settings files.

  • Practical Advice: If you can, do use a database for your settings or some form of clouded approach to get settings files OUT of your setup. Deploy your binaries only! And the templates needed to make settings files or registry settings on launch. That will help tremendously to simplify your setup.

    Links:

    • The other side of it: files not overwriting properly

    更多推荐

    我们安装 .exe 文件时不要覆盖现有文件

    本文发布于:2023-11-10 09:27:25,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1575000.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:文件   exe

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!