Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 安装.exe文件时不要覆盖现有文件_C#_Wix_Windows Installer - Fatal编程技术网

C# 安装.exe文件时不要覆盖现有文件

C# 安装.exe文件时不要覆盖现有文件,c#,wix,windows-installer,C#,Wix,Windows Installer,我已经安装了.exe应用程序,比如1.0版。安装应用程序后,我可以在本地路径C:\Program files x86中看到几个DLL和几个.XML配置文件。现在,在启动并安装新构建之后,我不想在本地路径中单独覆盖现有的XML文件。有什么办法吗 我的EXE是使用WIX安装程序创建的,该项目是在Visual Studio 2015中构建的 您可以做的一件事是防止安装程序卸载最新版本。可以为配置文件添加NeverOverwrite属性 我找到了这个解决方案。您可以做的一件事是阻止安装程序卸载最新版本。

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


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

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


我找到了这个解决方案。

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


我找到了这个解决方案。

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

如果您的升级计划延迟,例如afterInstallExecute,则升级是在旧产品上安装的,因此将应用文件覆盖规则。对于数据文件,这意味着如果文件在安装修改日期>创建日期之后更新,则不会被覆盖:

换言之,升级只会起作用,您根本不需要做任何事情


如果您的升级计划提前,例如afterInitinalize,则实际上是先卸载,然后再安装,因此您将在卸载过程中丢失文件。在这些情况下,通常最好在升级之前使用自定义操作将文件复制到安全位置,然后再删除现有产品,然后在升级中恢复。或者让应用程序将实际数据保存在一个副本文件中,该副本文件与安装中的文件不同,因此安装中的文件是一个模板,而不是实际的实时文件

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

如果您的升级计划延迟,例如afterInstallExecute,则升级是在旧产品上安装的,因此将应用文件覆盖规则。对于数据文件,这意味着如果文件在安装修改日期>创建日期之后更新,则不会被覆盖:

换言之,升级只会起作用,您根本不需要做任何事情


如果您的升级计划提前,例如afterInitinalize,则实际上是先卸载,然后再安装,因此您将在卸载过程中丢失文件。在这些情况下,通常最好在升级之前使用自定义操作将文件复制到安全位置,然后再删除现有产品,然后在升级中恢复。或者让应用程序将实际数据保存在一个副本文件中,该副本文件与安装中的文件不同,因此安装中的文件是一个模板,而不是实际的实时文件

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

让我试着为您描述一些您可能会面临的问题-如果不进行测试,您不可能提前预见

有关文件覆盖的一些详细信息 文件版本控制规则:MSI内置支持不覆盖自安装以来已修改的无版本文件。创建和修改日期不同。这些是。他们有点复杂和奇怪-你一定要读链接的内容-真正的麦考伊。因此,在更新过程中不应替换修改后的无版本文件,但这会带来很多复杂问题和麻烦,大多数人似乎都会陷入其中

主要升级文件恢复:对于意外的文件覆盖,最常见的复杂情况可能根本不是覆盖。它涉及到主要的升级,或者安装您的下一个产品版本,如果您愿意的话

如果使用主要升级来安装下一个版本,并在InstallExecuteSequence的早期计划RemoveExistingProducts,则所有文件都将实际卸载,然后以其原始版本重新安装。它们似乎已被覆盖,但已被卸载,然后重新安装

这一切都是由于一个非常奇怪的决定,即MSI将愉快地卸载修改过的文件,即使它们符合不被覆盖的条件。您需要的是一种定义文件不被卸载的方法。这就引出了下一点:

永久和从不覆盖标志:每个组件都有两个与文件覆盖和文件保存相关的重要设置:从不覆盖标志和永久标志。这确实是一个很好的方式来表明文件不应该被替换,也不应该被卸载。然而

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

如果只设置永久标志, 将根据文件版本规则覆盖文件-前提是在命令行中未使用诸如重新安装模式之类的功能指定任何修改,请参见下面的部分。我将需要再次验证这一点,以100%确定。有很多因素:组件只能在较旧或较新的设置中设置为永久性的-或者在两种设置中,主要升级可以提前或延迟卸载,重新安装模式有多种风格,等等。。。每个变量都可以更改覆盖行为

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

重新安装模式:重新安装模式是的修改器或禁用器。可以将安装期间的设置为amus,这将强制覆盖安装期间的所有文件,而不考虑上述文件版本规则

amus参数说明:

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

降级:可以在系统范围内降级共享文件。这些文件可能来自合并模块,因此人们可能没有意识到他们的目标是系统文件夹。Windows 10现在可以很好地保护其操作系统文件,但还有一些文件仍然可以在没有操作系统保护的情况下降级。 版本不一致:可能导致版本不一致,因为旧包可以在新包之后安装,并且只能降级部分共享文件。 设置擦除:可以降级或擦除非版本文件和注册表设置中的设置。 重新启动提示:由于尝试不必要地替换相同版本的在用文件,可能会导致请求的重新启动次数显著增加。有一些功能可以避免这种情况,但它们通常没有正确使用。 还有更多的…:还有几个更具体的问题。总有一天我会把它们都写下来。我想。也许不会吧?:-。 Windows文件保护WFP:也许我可以补充一点,某些旧合并模块包含现在受操作系统保护的文件,并尝试替换这些文件,这些文件可能会触发运行时错误。这现在由Windows 10以静默方式处理。 注册表:AMU的m和u开关将重置由组件写入的注册表数据,而不是完全不考虑a开关的自定义操作代码至少我上次尝试时是这样。在我的“高”部分,请参见潜在的反模式。 未知:GAC,WinSxS。我甚至不知道GAC是怎么运作的?肩并肩是设计上不可降级的吗?人们会想。除非你直接在程序集文件夹中翻找——希望这会触发一个运行时错误——我还没有尝试过。事实上,我认为不会。使用查看线程中的所有推文。 老实说,这有点疯狂,但这就是技术的工作原理。所以,让我们停止抱怨,努力解决这个问题。有什么办法可以解决这个问题

处理设置文件保存问题的一些选项 总之,我认为您有两种选择:

使用小型升级升级您的应用程序。这样,您的文件就永远不会被卸载和重新安装,因此也不会像大型升级那样被还原

次要升级不会卸载现有安装,而是直接升级。常规文件版本控制规则应用-除非使用重新安装模式修改此逻辑,否则不会替换已修改的非版本控制文件

然而,很少有人仅仅通过小的升级就成功了——他们是。我想说几乎没有

在InstallExecuteSequence早期使用RemoveExistingProducts进行主要升级,并为承载设置文件的组件启用永久和从不覆盖。当使用大型升级时,主要的选择是在早期和后期卸载旧版本之间进行,这种选择具有巨大的影响

这一部分需要清理。很快就会发生。。。。2019年12月:我们回来了。几年后。今天进行了一些小规模的清理,其他的就不多了。我会继续保证把这件事清理干净。空洞的承诺使世界转个不停。如果这一切看起来像是在抱怨,快速列表。MSI对以前的部署技术进行了至关重要的改进,但仍存在一些重大挑战

提前卸载意味着您所犯的任何组件引用错误都不会导致任何问题。如果你愿意,他们会更宽容。很多人最终使用t 特别是因为他的方法最能原谅组件引用错误和整体健壮性

提前卸载还意味着可以在升级过程中卸载和重新安装修改过的文件,从而使它们看起来被覆盖,但它们会按照上述方式恢复

解决上述问题的一个方法是将文件的宿主组件设置为永久性,并且从不覆盖

提前卸载意味着复杂的组件创建规则可能会被打破,升级仍将有效。打破组件创建规则是很常见的。如果使用这种方法,则应将升级期间要保留的文件设置为永久文件,并插入“永不覆盖”。这样可以防止卸载修改过的文件并安装新文件时出现问题,从而产生文件已被覆盖的印象

在InstallExecuteSequence后期对RemoveExistingProducts进行主要升级

延迟卸载主要升级安装不会卸载和重新安装旧设置和新设置中存在于同一位置的文件,即使相关文件未设置为永久文件,也不会覆盖,从而允许正确卸载文件,而无需添加任何自定义逻辑

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

相反,如果您没有将重新安装模式设置为amus,则它们将根据正常的文件版本控制规则被覆盖-在这种情况下,您将降级所有内容并清除设置

先前的答案:

设置文件的自定义备份机制:许多设置文件最终实现了复杂的自定义操作,用于备份设置文件,并在安装运行后将其放回原位

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

获取在其中运行的排序、模拟用户/系统上下文,并为这些自定义操作设置正确的条件,这一点都不简单

作为涉及的复杂性的一个具体示例,这里是前面的一个问题/答案,其中已经实现了这样一个功能,并且在确定到底发生了什么方面存在问题:

复杂性:正在进行非常复杂的调整,以使备份和恢复操作在不同的安装模式下在正确的时间进行—新安装、升级、修复、修改等

条件调试器轻实用提示!:为了解决复杂的条件,我喜欢通过现实世界中的条件测试,而不是过多的分析,非常具体。是的,无论如何,你都会失败——不知何故

以下是我使用的总体方法:。它本质上是一种对话框方法,来自一个有条件的自定义操作——当自定义操作在没有任何日志记录或复杂调试的情况下运行时,它会在现实生活中显示出来

只需在不同的模式下运行安装程序,看看是否会看到以下对话框:安装、卸载、修改、, 修复、修补、主要升级、暂停恢复

从部署中删除设置文件:这是我最喜欢的选项,尽管听起来可能有点奇怪。任何能使您的设置更简单、更简单的东西都会使它在实际使用中更可靠

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

在这些场景中,任何部署问题都不会干扰您宝贵的设置文件,除非您执行了不应该执行的奇怪的自定义操作

您的安装程序不知道这些设置文件是否存在,因此它们将始终处于单独状态。这通常是你想要的

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

我在以下回答中介绍了与每个用户和设置文件部署相关的一般问题:。请至少快速浏览一下,看看您是否可以通过消除复杂性而不是拥抱复杂性来改进部署

基本上,在设置中部署设置和用户文件有多种方法—活动设置、自我修复等

还有一些模板文件,您可以实例化这些文件,并将其排除在设置之外,如上文所述,不受任何干扰

在某些情况下,您可以使用应用程序内部默认值而不是设置文件,从而消除了所有部署方面的考虑

最后,您可以从网络数据库中检索设置,而不是使用老式的设置文件

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

链接:


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

让我试着为您描述一些您可能会面临的问题-如果不进行测试,您不可能提前预见

有关文件覆盖的一些详细信息 文件版本控制规则:MSI内置支持不覆盖自安装以来已修改的无版本文件。创建和修改日期不同。这些是。他们有点复杂和奇怪-你一定要读链接的内容-真正的麦考伊。因此,在更新过程中不应替换修改后的无版本文件,但这会带来很多复杂问题和麻烦,大多数人似乎都会陷入其中

主要升级文件恢复:对于意外的文件覆盖,最常见的复杂情况可能根本不是覆盖。它涉及到主要的升级,或者安装您的下一个产品版本,如果您愿意的话

如果使用主要升级来安装下一个版本,并在InstallExecuteSequence的早期计划RemoveExistingProducts,则所有文件都将实际卸载,然后以其原始版本重新安装。它们似乎已被覆盖,但已被卸载,然后重新安装

这一切都是由于一个非常奇怪的决定,即MSI将愉快地卸载修改过的文件,即使它们符合不被覆盖的条件。您需要的是一种定义文件不被卸载的方法。这就引出了下一点:

永久和从不覆盖标志:每个组件都有两个与文件覆盖和文件保存相关的重要设置:从不覆盖标志和永久标志。这确实是一个很好的方式来表明文件不应该被替换,也不应该被卸载。然而

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

如果仅设置永久标志,则将根据文件版本规则覆盖文件-前提是在命令行中未使用诸如重新安装模式之类的功能指定任何修改,请参见下面的部分。我将需要再次验证这一点,以100%确定。有很多因素:组件只能在较旧或较新的设置中设置为永久性的-或者在两种设置中,主要升级可以提前或延迟卸载,重新安装模式有多种风格,等等。。。每个变量都可以更改覆盖行为

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

重新安装模式:重新安装模式是的修改器或禁用器。可以将安装期间的设置为amus,这将强制覆盖安装期间的所有文件,而不考虑上述文件版本规则

amus参数说明:

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

降级:可以在系统范围内降级共享文件。这些文件可能来自合并模块,因此人们可能没有意识到他们的目标是系统文件夹。Windows 10现在可以很好地保护其操作系统文件,但还有一些文件仍然可以在没有操作系统保护的情况下降级。 版本不一致:可能导致版本不一致,因为旧包可以在新包之后安装,并且只能降级部分共享文件。 设置擦除:可以降级或擦除非版本文件和注册表设置中的设置。 重新启动提示:由于尝试不必要地替换相同版本的在用文件,可能会导致请求的重新启动次数显著增加。有一些功能可以避免这种情况,但它们通常没有正确使用。 还有更多的…:还有几个更具体的问题。总有一天我会把它们都写下来。我想。也许不会吧?:-。 Windows文件保护WFP:也许我可以添加某些遗留文件 ge模块包含现在受操作系统保护的文件,并试图替换这些文件,这些文件可能会触发运行时错误。这现在由Windows 10以静默方式处理。 注册表:AMU的m和u开关将重置由组件写入的注册表数据,而不是完全不考虑a开关的自定义操作代码至少我上次尝试时是这样。在我的“高”部分,请参见潜在的反模式。 未知:GAC,WinSxS。我甚至不知道GAC是怎么运作的?肩并肩是设计上不可降级的吗?人们会想。除非你直接在程序集文件夹中翻找——希望这会触发一个运行时错误——我还没有尝试过。事实上,我认为不会。使用查看线程中的所有推文。 老实说,这有点疯狂,但这就是技术的工作原理。所以,让我们停止抱怨,努力解决这个问题。有什么办法可以解决这个问题

处理设置文件保存问题的一些选项 总之,我认为您有两种选择:

使用小型升级升级您的应用程序。这样,您的文件就永远不会被卸载和重新安装,因此也不会像大型升级那样被还原

次要升级不会卸载现有安装,而是直接升级。常规文件版本控制规则应用-除非使用重新安装模式修改此逻辑,否则不会替换已修改的非版本控制文件

然而,很少有人仅仅通过小的升级就成功了——他们是。我想说几乎没有

在InstallExecuteSequence早期使用RemoveExistingProducts进行主要升级,并为承载设置文件的组件启用永久和从不覆盖。当使用大型升级时,主要的选择是在早期和后期卸载旧版本之间进行,这种选择具有巨大的影响

这一部分需要清理。很快就会发生。。。。2019年12月:我们回来了。几年后。今天进行了一些小规模的清理,其他的就不多了。我会继续保证把这件事清理干净。空洞的承诺使世界转个不停。如果这一切看起来像是在抱怨,快速列表。MSI对以前的部署技术进行了至关重要的改进,但仍存在一些重大挑战

提前卸载意味着您所犯的任何组件引用错误都不会导致任何问题。如果你愿意,他们会更宽容。很多人最终使用这种方法,特别是因为它最能原谅组件引用错误和整体健壮性

提前卸载还意味着可以在升级过程中卸载和重新安装修改过的文件,从而使它们看起来被覆盖,但它们会按照上述方式恢复

解决上述问题的一个方法是将文件的宿主组件设置为永久性,并且从不覆盖

提前卸载意味着复杂的组件创建规则可能会被打破,升级仍将有效。打破组件创建规则是很常见的。如果使用这种方法,则应将升级期间要保留的文件设置为永久文件,并插入“永不覆盖”。这样可以防止卸载修改过的文件并安装新文件时出现问题,从而产生文件已被覆盖的印象

在InstallExecuteSequence后期对RemoveExistingProducts进行主要升级

延迟卸载主要升级安装不会卸载和重新安装旧设置和新设置中存在于同一位置的文件,即使相关文件未设置为永久文件,也不会覆盖,从而允许正确卸载文件,而无需添加任何自定义逻辑

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

相反,如果您没有将重新安装模式设置为amus,则它们将根据正常的文件版本控制规则被覆盖-在这种情况下,您将降级所有内容并清除设置

先前的答案:

设置文件的自定义备份机制:许多设置文件最终实现了复杂的自定义操作,用于备份设置文件,并在安装运行后将其放回原位

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

获取在其中运行的排序、模拟用户/系统上下文,并为这些自定义操作设置正确的条件,这一点都不简单

作为涉及的复杂性的一个具体示例,这里是前面的一个问题/答案,其中已经实现了这样一个功能,并且在确定具体内容时存在一些问题 正在进行:

复杂性:正在进行非常复杂的调整,以使备份和恢复操作在不同的安装模式下在正确的时间进行—新安装、升级、修复、修改等

条件调试器轻实用提示!:为了解决复杂的条件,我喜欢通过现实世界中的条件测试,而不是过多的分析,非常具体。是的,无论如何,你都会失败——不知何故

以下是我使用的总体方法:。它本质上是一种对话框方法,来自一个有条件的自定义操作——当自定义操作在没有任何日志记录或复杂调试的情况下运行时,它会在现实生活中显示出来

只需在不同的模式下运行安装程序,看看是否会看到以下对话框:安装、卸载、修改、, 修复、修补、主要升级、暂停恢复

从部署中删除设置文件:这是我最喜欢的选项,尽管听起来可能有点奇怪。任何能使您的设置更简单、更简单的东西都会使它在实际使用中更可靠

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

在这些场景中,任何部署问题都不会干扰您宝贵的设置文件,除非您执行了不应该执行的奇怪的自定义操作

您的安装程序不知道这些设置文件是否存在,因此它们将始终处于单独状态。这通常是你想要的

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

我在以下回答中介绍了与每个用户和设置文件部署相关的一般问题:。请至少快速浏览一下,看看您是否可以通过消除复杂性而不是拥抱复杂性来改进部署

基本上,在设置中部署设置和用户文件有多种方法—活动设置、自我修复等

还有一些模板文件,您可以实例化这些文件,并将其排除在设置之外,如上文所述,不受任何干扰

在某些情况下,您可以使用应用程序内部默认值而不是设置文件,从而消除了所有部署方面的考虑

最后,您可以从网络数据库中检索设置,而不是使用老式的设置文件

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

链接: