向 app.config 添加了新的应用程序设置,但 MSI 不会安装它(不会覆盖)

Posted

技术标签:

【中文标题】向 app.config 添加了新的应用程序设置,但 MSI 不会安装它(不会覆盖)【英文标题】:Added new application setting to app.config but MSI won't install it (doesn't overwrite) 【发布时间】:2018-08-16 01:36:21 【问题描述】:

我们最近在旧版 winforms 应用程序 (.Net 4.6.1) 的 app.config(日志服务器的 URL)中添加了一个新的应用程序设置(不是用户设置)。

旧版本是 1.0.3,我们将所有程序集的版本更改为 1.0.4,并在安装项目(Visual Studio 2017 安装程序项目)中更改了版本以匹配它放弃了更改产品代码的弹出窗口,我们做到了。

安装运行正常(顺便说一下,其他东西也发生了变化,这些变化在新版本中是正确的),但我们的新 app.config 设置不是。奇怪的是,如果您手动删除配置文件并重新运行应用程序,它会重新创建配置文件,从而导致出现新设置。知道这里发生了什么吗?

谢谢!

【问题讨论】:

你在使用 WiX 吗? 否,适用于 Visual Studio 2017 的 Visual Studio 2017 安装程序项目扩展 恐怕我很少使用VS2017 Installer项目,而且我不知道此类项目中有任何XML文件更新功能。 WiX 是一个非常好的工具包,可以完成部署所需的任何事情。 Some quick start suggestions 如果您正在考虑迁移。 Visual Studio 安装程序项目不灵活。他们将每个文件都编写为它自己组件中的关键文件,并隐藏了组件的概念。它还使用默认的文件版本控制规则。这解释了您所看到的行为。 【参考方案1】:

您可能没有使用 WiX,但在我注意到您没有将 WiX 添加为标签之前,我将添加我所写的内容。必须学会阅读。


这可能是 MSI / WiX 部署中最常见的问题,以及在主要升级期间清除配置设置。我假设您在安装期间已将 app.config 文件设置为永久文件,以便在重大升级期间保留它?

可能发生的情况是您已将配置文件安装为文件,但它应该安装为一堆 XML 配置设置,可以合并到目标文件中。

The MSI file versioning rules 尝试保留安装后已修改的非版本控制文件。因此,如果文件的创建和修改日期在升级时不同,则不会覆盖非版本化文件。如果没有最新的所需值,您的文件将显示为原样。它已被“保存”。

您可以更新您的 WiX 源以使用适当的 WiX XML 元素设置所需的值。有两个不同的元素是相关的:

XmlConfig Element XmlFile Element

关于这两个元素之间的差异,我引用 Bob Arnson(WiX 开发人员):“您可以使用 XmlConfig 执行 XmlFile 支持的所有(以及更多)操作,但它需要额外的使用 XmlFile 进行创作不是必需的。 XmlFile 最擅长修改您正在安装的 XML 文件(例如,添加反映文件安装路径的属性);它无法在卸载时删除修改,但如果您的安装程序安装了该文件,它将被卸载。 XmlConfig 最擅长修改共享的 XML 文件,因为它支持卸载修改。" (source)。


我发现这些 XML 内容非常繁琐,而且我可能不会使用最新最好的技术,但这里有一个快速示例。彻底测试——尤其是卸载和升级场景——我所做的有限测试:

这是我的测试 XML 文件(实际上是作为文件安装然后更新的)。请检查您保存的文件的编码 - some issues with encoding have been reported - 不确定当前状态是什么:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <ExistingConfig>
    <bindingRedirect oldVersion="0.0.0" newVersion="0.0.0" />
  </ExistingConfig>
</configuration>

这是将更新文件(并安装文件)的 WiX sn-p。将上述 XML 测试文件放在 WXS 源文件旁边,或在构建 MSI 之前指定正确的源路径。

<Component Feature='ProductFeature'>

 <!--Installs the base file-->
 <File Source='app.config' />

 <!--Create New Element-->
 <util:XmlFile Id='XmlSettings1' File='[#app.config]' Action='createElement' 
               Name='MyConfig' ElementPath='//configuration' Sequence='1' />

 <!--Set New Value-->
 <util:XmlFile Id='XmlSettings2' File='[#app.config]' Action='setValue' 
              Name='newVersion' Value='6.6.8' ElementPath='//configuration/MyConfig' Sequence='2' />

<!--Set New Value-->
<util:XmlFile Id='XmlSettings3' File='[#app.config]' Action='setValue' 
              Name='Server' Value='Pusevov' ElementPath='//configuration/MyConfig' Sequence='3' />

<!--Update Existing Value, Existing Element-->
<util:XmlFile Id='XmlSettings4' File='[#app.config]'
  Action='setValue' Name='newVersion' Value='7.7.7' ElementPath='//configuration/ExistingConfig/bindingRedirect' Sequence='4' />

</Component>

我希望这有某种意义。就像我说的,我发现这有时很繁琐且容易出错,但其他用于此类更新的工具也是如此。请记住首先尝试使用原始测试用例并进行测试安装以测试运行时错误。做一些可行的小东西,然后在其上进行构建——这显然是不言而喻的,但一次尝试所有这些是很诱人的。 “洞里开火,寻找掩护!”。

一些安全链接:

Firegiant Tutorial on XML Deleting XML element with XmlConfig extension in WIX using XPath WIX util:xmlfile File name is Source attribute WIX v3 and XmlConfig / XmlFile troubleshooting(从 Wayback Machine 中复活) Very step-by-step blog on WiX and XML How do I force wix to update a file before manipulating it on an upgrade Getting app settings for config files during WiX based install

【讨论】:

我可以使用patch.msp 做到这一点吗?我的 msp 有增量文件或初始 msi 和最新构建 msi 之间的更改文件。我的 patch.msp 无法应用并给出错误。我的 web.config 组件最初设置为 NeverOverwrite=yes。现在有了我的新版本,我正在将组件重置为 NeverOverwrite=no。然后,我从 msi1 和 msi_latest 生成一个 patch.msp,并且该补丁无法应用。有什么想法吗? 补丁只是一种分发方法,用于已经必须工作的更新。在使用补丁进行更多测试之前,首先尝试运行完整的 MSI 以查看它是否有效。是小升级补丁吗? 好的,我可以试试,但是我需要设置 Neveroverwrite=no 才能成功覆盖这个文件吗? 保持永不覆盖,写入将由 XML 文件的 WiX 自定义操作完成,而不是由 MSI 本身完成。 不,它只是一个小更新。不是小升级。我假设您在 a.b.c.d 中的意思是 'b' 说 minor upgrade 。如有错误请指正。

以上是关于向 app.config 添加了新的应用程序设置,但 MSI 不会安装它(不会覆盖)的主要内容,如果未能解决你的问题,请参考以下文章

App.config:用户与应用程序范围

基于Debug模式windows应用程序app.config设置

如何编辑应用程序配置设置? App.config 最好的方法是啥?

将单选按钮添加到现有组 - MFC

EF5 codefirst 和 SQL CE 的 App.config 设置

设置文件与 app.config [重复]