在运行时更改 App.config

Posted

技术标签:

【中文标题】在运行时更改 App.config【英文标题】:Changing App.config at Runtime 【发布时间】:2011-01-01 19:14:48 【问题描述】:

我正在为我们正在开发的系统编写一个测试 WinForms / C# / .NET 3.5 应用程序,我们需要在运行时在 .config 文件之间切换,但结果证明这是一场噩梦。

场景如下:WinForms 应用程序旨在测试一个 WebApp,分为 5 个子系统。测试过程处理子系统之间发送的消息,并且要使该过程成功,每个子系统都必须拥有自己的 .config 文件。

对于我的测试应用程序,我编写了 5 个单独的配置文件。我希望我能够在运行时在这 5 个文件之间切换,但问题是:我可以以编程方式多次编辑应用程序 .config 文件,但这些更改只会生效一次。我一直在寻找一个表格来解决这个问题,但我仍然没有成功。

我知道问题定义可能有点混乱,但如果有人帮助我,我将不胜感激。

提前致谢!

--- 更新 01-06-10 ---

有些事情我之前没有提到。最初,我们的系统是一个 Web 应用程序,每个子系统之间都有 WCF 调用。出于性能测试的原因(我们使用的是 ANTS 4),我们必须创建程序集的本地副本并从测试项目中引用它们。这听起来可能有点不对劲,但我们找不到令人满意的方法来衡量远程应用程序的性能。

--- 结束更新---

这就是我正在做的事情:

public void UpdateAppSettings(string key, string value)

    XmlDocument xmlDoc = XmlDocument.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

    foreach (XmlElement item in xmlDoc.DocumentElement)
    
        foreach (XmlNode node in item.ChildNodes)
        
            if (node.Name == key)
            
                node.Attributes[0].Value = value;
                break;
            
        
    

    xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

    System.Configuration.ConfigurationManager.RefreshSection("section/subSection");    

【问题讨论】:

重复/相关? ***.com/questions/1542171/… 我已经尝试过这些方法...问题是,我要更改的标签在 之外。我还尝试创建新的 AppDomain 并为它们设置不同的 .config 文件,但它也不起作用。 【参考方案1】:

我的猜测是您第一次并没有真正关闭文件句柄,因此 Windows 不会“看到”您进行以后的更改。

我的建议是使用对 IIS 的 API 调用并关闭 Web 应用程序(和池),进行更改,然后打开 Web 应用程序。这样您就可以确定它会重新读取文件并为每个测试提供一个“干净”的环境。

【讨论】:

我用一些细节更新了这个问题。基本上,在这种情况下(性能测试)我们没有使用 IIS,程序集是在本地引用的。我正在使用 Xml 库写入 .config 文件。在执行过程中,我可以看到文件正在被写入和更改。【参考方案2】:

假设配置文件的文件句柄在配置文件被读取和处理后关闭,我会向应用程序发送一条消息,告诉它在你更新文件后重新读取配置文件。如果这种方法不起作用,那么我怀疑(正如霍根建议的那样)文件句柄没有关闭。您从文件打开、读取和关闭系统调用中得到什么错误代码? (使用perror 报错信息)

【讨论】:

这个方法很有趣,但是你能给我一些关于如何发送这个消息到应用程序的步骤吗?我尝试调用 ConfigurationManager.RefreshSection() 但没有成功。 @born to hula:@runtime怎么改配置?我会使用相同的方法让应用程序重新读取配置文件。您使用什么语言和操作系统?测试期间发送到应用程序的消息是什么?应用程序的输入是否来自网页?回答这些问题将为您提供一些关于适合您情况的最佳方法的线索。 我正在使用 XmlDocument 更改 .config 文件(请参阅更新后的问题)。但是,无论我更改多少次,更改只会在执行上下文中反映一次。我正在使用 C# 和 Windows XP。应用程序的输入直接来自表单。基本上,主要输入是一条消息,从中可以创建各种对象。 @born to hula: 我的经验是在 Unix 上;不在 Windows 上。对不起。【参考方案3】:

更新

下面的解决方案不起作用,因为 XmlDocument 没有处理,并且似乎某些版本的 .net 在给定文件路径时无法正确关闭。解决方案(链接中的示例代码)是打开一个流,该流将执行处置并将该流传递给保存函数。

这里显示了一个解决方案。 http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


下面的旧东西

试试这个:

注意,我改成了 xpath,但已经有一段时间了,所以我可能弄错了 xpath,但无论如何你应该使用 xpath 而不是遍历树。如您所见,它更加清晰。

重要的是using 声明将dispose(),我认为这是你的问题。

告诉我,祝你好运。

  public void UpdateAppSettings(string key, string value)
  
    using (XmlDocument xmlDoc = new XmlDocument())
    
      xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
      xmlDoc.DocumentElement.FirstChild.SelectSingleNode("descendant::"+key).Attributes[0].Value = value;
      xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
    
    System.Configuration.ConfigurationManager.RefreshSection("section/subSection");
  

【讨论】:

有点道理,问题是XmlDocument没有实现IDisposable,所以不能使用“using”范围。 好吧,我有一点猜测,情况并非如此。我正在使用框架 .NET 3.5。此外,我认为如果文件流仍处于打开状态,那么在我第二次尝试写入 xml 文件时,我会得到一个异常......但无论如何谢谢。 嗯... .net 框架存在一个已记录的问题,示例代码看起来与您的完全相同,我为您提供了解决该问题的代码链接,您不会去试试看?你不想解决这个问题吗? 我会试一试,并会向您更新结果。感谢您的帮助。 我试过了,显然结果是一样的。无论如何,谢谢。【参考方案4】:

我知道这是一个相当古老的线程,但我无法让列出的方法起作用。这是 UpdateAppSettings 方法的更简单版本(使用 .NET 4.0):

private void UpdateAppSettings(string theKey, string theValue)
        
            Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (ConfigurationManager.AppSettings.AllKeys.Contains(theKey))
            
                configuration.AppSettings.Settings[theKey].Value = theValue;
            

            configuration.Save(ConfigurationSaveMode.Modified);

            ConfigurationManager.RefreshSection("appSettings");
        

可读性强,避免使用 Xpath 等遍历 app.config。 注意:以上代码的灵感来自于 MSDN 上的thissn-p。

【讨论】:

在我的 winforms 应用程序中不起作用,执行良好,但 *.config 没有变化

以上是关于在运行时更改 App.config的主要内容,如果未能解决你的问题,请参考以下文章

在片段中在运行时更改方向时更改布局而不重新创建视图

在运行时更改对话框字体

如何在运行时更改 CurrentCulture?

在运行时更改语言

Diesel 可以在运行时更改架构吗?

我们可以在运行时更改参数值吗