8

我正在为我们正在开发的系统编写一个测试 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");    
}
4

4 回答 4

26

我知道这是一个相当古老的线程,但我无法让列出的方法起作用。这是 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 上的这个片段。

于 2012-04-11T16:34:42.130 回答
3

更新

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

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


下面老东西

试试这个:

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

重要的一点是using声明 which will 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");
  }
于 2010-01-06T16:43:04.943 回答
1

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

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

于 2010-01-05T20:25:57.017 回答
0

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

于 2010-01-05T20:54:15.187 回答