我的应用程序包含多个文件,这些文件包含配置参数以及随用户使用应用程序而更改的其他数据。这些文件可能会随着我的软件的更新版本而改变,但用户也可以修改它们(或者它们可能会被应用程序本身更改)。基本上,我正在寻找一种解决方案来防止用户对这些文件的更改被覆盖,但也是一种在用户升级我的软件时安装可能更新的文件的方法。
使用RPM on * NIX,您可以使用%config函数将文件定义为配置文件,然后RPM将重命名现有文件(如果存在)并在升级时安装新文件(可能不理想,但是对于WiX,我可以忍受这样的事情。
我想将配置文件安装到子目录甚至是不同的名称(例如default.cfg),然后使用WiX中的<CopyFile>
元素将文件复制到正确的位置。这样,默认文件将在安装时删除并在升级时被覆盖,但实际用户文件将保持不变。不幸的是,对于<CopyFile>
,Windows Installer仍然希望管理(和删除)目标文件。
我还考虑过在WixUtilExtension中使用QtExec操作来基本上“复制default.cfg reallocation.cfg”,但这不太有效,而且有点像黑客。
处理此问题的正确方法是什么?
答案 0 :(得分:4)
我的建议通常是将用户可编辑的内容放在单独的文件中,并通过应用程序而不是安装来管理。这也意味着单独的文件是“用户内容”,应该不在安装之外。
我发现尝试以声明方式迁移用户数据看起来很困难。尝试在设置时执行此操作,当您需要考虑所有这些情况的安装,卸载,修复,修补和回滚时,只会使情况变得更糟。
例如,RPM行为对“修复”的作用是什么。将用户数据复制出来并用一个好的文件替换它?这可能是正确的60% - 80%的时间。并卸载,该文件应删除?如果用户只是升级到下一个版本,这很棘手。
同样,最好让他们决定如何处理他们对配置的调整。 IMHO。
答案 1 :(得分:2)
我认为没有“干净”的方法可以做到这一点,因为msi项目必须能够完全按设计卸载。我认为解决此问题的最佳方法是使用自定义操作执行批处理文件并将配置文件更新逻辑放在该批处理文件中。自定义操作如下所示(仅限相关部分):
<Directory Id="MYDIR" Name="MyDir">
<Component Id="update.cmd" Guid="YOUR-GUID">
<File Id="update.cmd" Name="update.cmd" KeyPath="yes"
Source="source\update.cmd" />
</Component>
</Directory>
<CustomAction Id='RunUpdate' Directory='MYDIR'
ExeCommand='[SystemFolder]cmd.exe /c update.cmd' Return='ignore'/>
<InstallExecuteSequence>
<Custom Action='RunUpdate' After='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>