update app.config file at runtime
You are using applicationSettings
not appSettings
.
The two are different sections of you config file.
To use an entry in the applicationSettings
you use this syntax:
string result = Client.Properties.Settings.Default.client_postCodeRef_Service;
also note that you can't easily change the value of an applicationSetting entry from inside your program.
A detailed discussion on the pros and cons of applicationSettings and AppSettings can be found here
Change app.config programmatically at the runtime
Because you are using a custom section you need to do it with:
var xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var path = @"//oracle.manageddataaccess.client/version/settings/setting[@name='TNS_ADMIN']";
var attrs = xmlDoc.SelectSingleNode(path).Attributes["value"].Value = "some value";
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
ConfigurationManager.RefreshSection(path);
This should work in case of default appSettings
section:
System.Configuration.Configuration cnf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cnf.AppSettings.Settings["TNS_ADMIN"].Value = "my value";
cnf.Save(ConfigurationSaveMode.Modified);
Documentation
Modify app.config system.diagnostics section at runtime
You can locate the path to the app.exe.config
file through the ConfigurationManager
, then load the config file as an XDocument
.
string configPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
XDocument config = XDocument.Load(configPath);
XElement diagnostics = config.Descendants().FirstOrDefault(e => e.Name == "system.diagnostics");
if (diagnostics == default(XElement))
{
/// <system.diagnostics> element was not found in config
}
else
{
/// make changes within <system.diagnostics> here...
}
config.Save(configPath);
Trace.Refresh(); /// reload the trace configuration
Once the required changes are made, save the XDocument
back to disk, and call Trace.Refresh()
to reload the trace configuration.
See MSDN regarding the Trace.Refresh
method here.
How to modify my App.exe.config keys at runtime?
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["UserId"].Value = "myUserId";
config.Save(ConfigurationSaveMode.Modified);
You can read about ConfigurationManager here
Changing App.config at Runtime
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");
}
Change default app.config at runtime
The hack in the linked question works if it is used before the configuration system is used the first time. After that, it doesn't work any more.
The reason:
There exists a class ClientConfigPaths
that caches the paths. So, even after changing the path with SetData
, it is not re-read, because there already exist cached values. The solution is to remove these, too:
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
public abstract class AppConfig : IDisposable
{
public static AppConfig Change(string path)
{
return new ChangeAppConfig(path);
}
public abstract void Dispose();
private class ChangeAppConfig : AppConfig
{
private readonly string oldConfig =
AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
private bool disposedValue;
public ChangeAppConfig(string path)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
ResetConfigMechanism();
}
public override void Dispose()
{
if (!disposedValue)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);
ResetConfigMechanism();
disposedValue = true;
}
GC.SuppressFinalize(this);
}
private static void ResetConfigMechanism()
{
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, 0);
typeof(ConfigurationManager)
.GetField("s_configSystem", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
typeof(ConfigurationManager)
.Assembly.GetTypes()
.Where(x => x.FullName ==
"System.Configuration.ClientConfigPaths")
.First()
.GetField("s_current", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
}
}
}
Usage is like this:
// the default app.config is used.
using(AppConfig.Change(tempFileName))
{
// the app.config in tempFileName is used
}
// the default app.config is used.
If you want to change the used app.config for the whole runtime of your application, simply put AppConfig.Change(tempFileName)
without the using somewhere at the start of your application.
Can I get settings from app.config at run time rather than when compiled?
Found It!
The problem was occurring in a class library.
Although I create the settings in the class library and the settings get added to the app.config, it doesn't actually look there to retrieve them. Instead it's the web.config of the parent consuming the class library.
I put the settings in web.config and it appears to work.
Related Topics
Newtonsoft.JSON Assembly Package Version Mismatch
Sqlite .Net Performance, How to Speed Up Things
Find If Point Lies on Line Segment
What Is the Correct Way to Cancel an Async Operation That Doesn't Accept a Cancellationtoken
Authentication with Old Password No Longer Supported, Use 4.1 Style Passwords
Where Are Clr-Defined Methods Like [Delegate].Begininvoke Documented
How to Know the Repeating Decimal in a Fraction
C# - Inconsistent Math Operation Result on 32-Bit and 64-Bit
Broadcastblock with Guaranteed Delivery in Tpl Dataflow
Extension Method on Enumeration, Not Instance of Enumeration
How to Use Multi Color in Richtextbox
How to Create a New Operator in C#
Return All Enumerables with Yield Return at Once; Without Looping Through
The Operation Cannot Be Completed Because the Dbcontext Has Been Disposed Using MVC 4
How to Connect to a Ms Access File (Mdb) Using C#
How to Take All But the Last Element in a Sequence Using Linq