C# 在运行时更改 App.config
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2008800/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing App.config at Runtime
提问by born to hula
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.
我正在为我们正在开发的系统编写一个测试 WinForms/C#/.NET 3.5 应用程序,我们需要在运行时在 .config 文件之间切换,但结果证明这是一场噩梦。
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.
场景如下:WinForms 应用程序旨在测试一个 WebApp,分为 5 个子系统。测试过程处理子系统之间发送的消息,为了使该过程成功,每个子系统都必须拥有自己的 .config 文件。
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.
对于我的测试应用程序,我编写了 5 个单独的配置文件。我希望我能够在运行时在这 5 个文件之间切换,但问题是:我可以以编程方式多次编辑应用程序 .config 文件,但这些更改只会生效一次。我一直在寻找解决这个问题的表格很长时间,但我仍然没有成功。
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 ---
--- 更新 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.
有件事我之前没有提到。最初,我们的系统是一个 Web 应用程序,每个子系统之间都有 WCF 调用。出于性能测试的原因(我们使用的是 ANTS 4),我们必须创建程序集的本地副本并从测试项目中引用它们。这听起来可能有点错误,但我们找不到一种令人满意的方法来衡量远程应用程序的性能。
--- 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");
}
采纳答案by Hogan
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.
下面的解决方案不起作用,因为 XmlDocument 没有处理,并且在给定文件路径时,某些版本的 .net 似乎无法正确关闭。解决方案(链接中的示例代码)是打开一个流,该流将执行处置并将该流传递给保存函数。
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.
请注意,我更改为 xpath,但已经有一段时间了,所以我可能将 xpath 弄错了,但无论如何您应该使用 xpath 而不是遍历树。如您所见,它更加清晰。
The important point is the using
statement which will dispose()
, which I think was your problem.
重点是using
语句 which will dispose()
,我认为这是你的问题。
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");
}
回答by Hogan
My guess is you are not really closing the file handle the first time so windows does not "see" you making the later changes.
我的猜测是您第一次并没有真正关闭文件句柄,因此 Windows 不会“看到”您进行后续更改。
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.
我的建议是使用对 IIS 的 API 调用并关闭 Web 应用程序(和池),进行更改,打开 Web 应用程序。这样您就可以确定它会重新读取文件并为每个测试提供一个“干净”的环境。
回答by David Harris
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)
假设在读取和处理配置文件后关闭了配置文件的文件句柄,我会向应用程序发送一条消息,告诉它在您更新文件后重新读取配置文件。如果这种方法不起作用,那么我怀疑(正如霍根建议的那样)文件句柄没有关闭。你从文件打开、读取和关闭系统调用中得到什么错误代码?(使用perror上报错误信息)
回答by Sudhanshu Mishra
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):
我知道这是一个很旧的线程,但是我无法使列出的方法起作用。这是 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");
}
Pretty readable and avoids having to traverse the app.config using Xpath or the like. Note: The code above is inspired from thissnippet on MSDN.
非常易读,避免使用 Xpath 等遍历 app.config。注意:上面的代码灵感来自MSDN 上的这个片段。