在运行时更改 App.config

发布于 2024-08-16 18:06:50 字数 1226 浏览 2 评论 0原文

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

I'm writing a test WinForms / C# / .NET 3.5 application for the system we're developing and we fell in the need to switch between .config files at runtime, but this is turning out to be a nightmare.

Here's the scene: the WinForms application is aimed at testing a WebApp, divided into 5 subsystems. The test process works with messages being sent between the subsystems, and for this process to be successful each subsystem got to have its own .config file.

For my Test Application I wrote 5 separate configuration files. I wish I was able to switch between these 5 files during runtime, but the problem is: I can programatically edit the application .config file numerous times, but these changes will only take effect once. I've been searching a long time for a form to address this problem but I still wasn't successful.

I know the problem definition may be a bit confusing but I would really appreciate it if someone helped me.

Thanks in advance!

--- UPDATE 01-06-10 ---

There's something I didn't mention before. Originally, our system is a Web Application with WCF calls between each subsystem. For performance testing reasons (we're using ANTS 4), we had to create a local copy of the assemblies and reference them from the test project. It may sound a bit wrong, but we couldn't find a satisfying way to measure performance of a remote application.

--- End Update ---

Here's what I'm doing:

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");    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少钕鈤記 2024-08-23 18:06:50

我知道这是一个相当古老的线程,但我无法使列出的方法起作用。下面是 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。
注意:上面的代码的灵感来自this MSDN 上的片段。

I understand this is quite an old thread, but I could not get the listed methods to work. Here is a simpler version of the UpdateAppSettings method (using .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");
        }

Pretty readable and avoids having to traverse the app.config using Xpath or the like.
Note: The code above is inspired from this snippet on MSDN.

三五鸿雁 2024-08-23 18:06:50

更新

下面的解决方案不起作用,因为 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");
  }

UPDATE

The solution below did not work because XmlDocument does not dispose and it seems some versions of .net do not close correctly when given a file path. The solution (example code in the link) is to open a stream which will do a dispose and pass that stream to the save function.

A solution is shown here. http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Old stuff below

Try this:

Note, I changed to xpath, but it has been a while so I might have gotten the xpath wrong, but in any case you should use xpath and not walk the tree. As you can see it is much clearer.

The important point is the using statement which will dispose(), which I think was your problem.

Let me know, good luck.

  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");
  }
此生挚爱伱 2024-08-23 18:06:50

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

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

My guess is you are not really closing the file handle the first time so windows does not "see" you making the later changes.

My suggestions is to use an API call to IIS and turn off the web app (and pool), make the change, turn on the web app. This way you are sure it will re-read the file and have a "clean" environment for each test.

毅然前行 2024-08-23 18:06:50

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

Assuming that the file handle to the configuration file is closed after the configuration file has been read and processed, I would send a message to the application to tell it to re-read the configuration file after you have updated the file. If this approach is not working, then I suspect (as Hogan suggested) that the file handle is not closed. What error codes are you getting from the file opening, reading and closing system calls? (use perror to report the error message)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文