C# 在运行时更改App.config

C# 在运行时更改App.config,c#,.net-3.5,configuration-files,app-config,configurationmanager,C#,.net 3.5,Configuration Files,App Config,Configurationmanager,我正在为我们正在开发的系统编写一个测试WinForms/C#/.NET 3.5应用程序,我们需要在运行时在.config文件之间切换,但这是一场噩梦 场景如下:WinForms应用程序旨在测试一个WebApp,分为5个子系统。测试过程处理子系统之间发送的消息,为了使该过程成功,每个子系统都有自己的.config文件 对于我的测试应用程序,我编写了5个单独的配置文件。我希望能够在运行时在这5个文件之间切换,但问题是:我可以通过编程多次编辑application.config文件,但这些更改只会生效

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

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

对于我的测试应用程序,我编写了5个单独的配置文件。我希望能够在运行时在这5个文件之间切换,但问题是:我可以通过编程多次编辑application.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");    
}

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


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

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

更新

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

这里显示了一个解决方案


下面的旧东西

试试这个:

注意,我改为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");
  }

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

可读性强,避免了使用Xpath或类似工具遍历app.config。
注意:上面的代码源于MSDN上的代码片段。

dup/related?我已经试过这些方法了。。。问题是,我要换的标签在外面。我还尝试创建新的AppDomain并为其设置不同的.config文件,但也不起作用。这种方法很有趣,但您能告诉我如何将此消息发送到应用程序的一些步骤吗?我试图调用ConfigurationManager.RefreshSection(),但没有成功。@born to hula:如何更改@runtime的配置?我将使用相同的方法让应用程序重新读取配置文件。您使用的是什么语言和操作系统?在测试期间向应用程序发送的消息是什么?应用程序的输入是否来自网页?回答这些问题可以为您提供一些关于最佳解决方案的线索。我正在使用XmlDocument更改.config文件(请参阅更新的问题)。但是,无论我更改了多少次,这些更改只会在执行上下文中反映一次。我正在使用C#和Windows XP。应用程序的输入直接来自表单。基本上,主要输入是一条消息,从中可以创建各种对象。@born to hula:我的经验是在Unix上;不是在窗户上。对不起,我用一些细节更新了问题。基本上,在这个上下文(性能测试)中,我们没有使用IIS,而是在本地引用程序集。我正在使用Xml库写入.config文件。在执行过程中,我可以看到文件正在被写入和更改。这有点道理,问题是XmlDocument没有实现IDisposable,所以不可能使用“using”范围。好吧,我有点猜测情况并非如此。我使用的是framework.net3.5。此外,我认为如果文件流仍然是打开的,当我第二次尝试写入xml文件时,我会得到一个异常。。。不过还是谢谢你。嗯。。。.net framework中有一个记录在案的问题,其示例代码与您的完全相同,我为您提供了一个指向解决该问题的代码的链接,您不打算尝试吗?你不想解决这个问题吗?我会尝试一下,并将结果更新给你。谢谢你的帮助。我已经试过了,结果显然是一样的。无论如何谢谢你,伙计。在我的winforms应用程序中不工作,执行良好,但在*.config中没有更改
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");
        }