我正在使用 WiX 3.8 并尝试在小更新时更新我现有的 .config 文件,但我很难理解如何实现这一点。
我创建了一个自定义操作来从现有配置文件中读取值,但不知道如何将它们插入到新文件中?
我关注了这篇文章:让 WiX 升级缺少项目的配置文件(以及随后的这个:如何使用 wix 将多个元素添加到 XML 配置文件中?),但设置似乎没有被以前的值覆盖,可以有人给我指点吗?
基本上我想保留用户在安装过程中输入的设置,但如果它从一个版本更改为另一个版本,则覆盖其余的配置。
我正在使用 WiX 3.8 并尝试在小更新时更新我现有的 .config 文件,但我很难理解如何实现这一点。
我创建了一个自定义操作来从现有配置文件中读取值,但不知道如何将它们插入到新文件中?
我关注了这篇文章:让 WiX 升级缺少项目的配置文件(以及随后的这个:如何使用 wix 将多个元素添加到 XML 配置文件中?),但设置似乎没有被以前的值覆盖,可以有人给我指点吗?
基本上我想保留用户在安装过程中输入的设置,但如果它从一个版本更改为另一个版本,则覆盖其余的配置。
简而言之,这是 Windows Installer 的一个巨大弱点。MSI 本身不支持 XML 操作。在其核心,Windows Installer 以原子方式处理文件,因为 XML 文件在某种意义上就像整个注册表配置单元。
WiX 添加了 XML 转换功能来解决第一个问题,但第二个问题确实无法解决。您必须拥有原始 XML、当前 XML 和提议的 XML 的副本,然后您必须有业务规则来知道要合并什么和不合并什么。
为了首先避免这个问题,我个人建议是有 2 个 XML 文件。一种已安装并由安装程序完全拥有 (stock.xml),另一种未由安装程序接触并由应用程序拥有 (override.xml)。然后在您的 XML 阅读器中,override.xml 的内容优先于 stock.xml 的内容。通过这种方式,安装程序总是可以做它最擅长的事情)安装文件,而无需进行复杂的数据处理。
我目前使用自定义操作和 XmlConfig 的组合来执行此操作。
自定义操作在 CostFinalize 之后运行,并从配置文件中读取当前值并将它们保存在公共属性中。
string configFile = Path.Combine(session["INSTALLLOCATION"], "app.exe.config");
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = configFile;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
session["OLD_PRESERVEDVALUE"] = config.AppSettings.Settings["PreservedValue"].Value;
然后我有一个如下所示的 XmlConfig 条目,它设置公共属性中的保留值:
<Component Id="RestoreOldPreservedValue" Guid="<GUID>" >
<Condition>OLD_PRESERVEDVALUE</Condition>
<CreateFolder/>
<util:XmlConfig
Id='RestoreOldPreservedValue'
Action='create'
On='install'
Node='value'
ElementPath='/configuration/applicationSettings/app.Properties.Settings/setting[\[]@name="PreservedValue"[\]]/value'
File='[#app.exe.config]'
Value='[OLD_PRESERVEDVALUE]'>
</util:XmlConfig>
</Component>
我的下一次迭代将是让自定义操作直接在 XmlConfig 表中创建条目。
最终的解决方案是一个 WiX 扩展,它填充一个自定义表并安排一个自定义操作,该操作保存在 CostFinalize 之后要保留的值,然后另一个自定义操作在新配置文件被复制后恢复这些值安装程序。