Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing App.config at Runtime

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");    
}
like image 902
born to hula Avatar asked Jan 05 '10 20:01

born to hula


2 Answers

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.

like image 104
Sudhanshu Mishra Avatar answered Sep 24 '22 14:09

Sudhanshu Mishra


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");
  }
like image 24
Hogan Avatar answered Sep 23 '22 14:09

Hogan