title: Loading Properties.Settings from a different file at runtime
body: <p>Is there any way to load settings from a different file other than the default <code>App.config</code> file at runtime?  I'd like to do this after the default config file is loaded.</p>
  
  <p>I use the <code>Settings.Settings</code> GUI in Visual Studio to create my <code>App.config</code> file for me.  The config file ends up looking like this:</p>
  
  <pre><code>    &lt;?xml version="1.0" encoding="utf-8" ?&gt;
      &lt;configuration&gt;
          &lt;configSections&gt;
              &lt;sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" &gt;
          &lt;section name="SnipetTester.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /&gt;
      &lt;/sectionGroup&gt;
      &lt;/configSections&gt;
        &lt;applicationSettings&gt;
          &lt;SnipetTester.Properties.Settings&gt;
            &lt;setting name="SettingSomething" serializeAs="String"&gt;
              &lt;value&gt;1234&lt;/value&gt;
            &lt;/setting&gt;
          &lt;/SnipetTester.Properties.Settings&gt;
        &lt;/applicationSettings&gt;
      &lt;/configuration&gt;
  </code></pre>
  
  <p>In code, I'm able to access the settings like this:</p>
  
  <pre><code>Console.WriteLine("Default setting value:  " + Properties.Settings.Default.SettingSomething);
  </code></pre>
  
  <p>The idea is that when the application is run, I should be able to specify a config file at run time and have the application load the config file into the <code>Properties.Settings.Default</code> object instead of using the default <code>app.config</code> file.  The formats of the config files would be the same, but the values of the settings would be different.</p>
  
  <p>I know of a way to do this with the <code>ConfigurationManager.OpenExeConfiguration(configFile);</code>.  However, in the tests that I've run, it doesn't update the <code>Properties.Settings.Default</code> object to reflect the new values from the config file.</p>
  
  <hr>
  
  <p>After thinking about this a bit longer, I've been able to come up with a solution that I like a little better.  I'm sure it has some pitfalls, but I think it'll work for what I need it to do.</p>
  
  <p>Essentially, the <code>Properties.Settings</code> class is automatically generated by Visual Studio; it generates the code for the class for you.  I was able to find where the code was generated and add a few function calls to load a config file on its own.  Here's my addition:</p>
  
  <pre><code>internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 
  {
      //Parses a config file and loads its settings
      public void Load(string filename)
      {
          System.Xml.Linq.XElement xml = null;
          try
          {
              string text = System.IO.File.ReadAllText(filename);
              xml = System.Xml.Linq.XElement.Parse(text);
          }
          catch
          {
              //Pokemon catch statement (gotta catch 'em all)
  
              //If some exception occurs while loading the file,
              //assume either the file was unable to be read or
              //the config file is not in the right format.
              //The xml variable will be null and none of the
              //settings will be loaded.
          }
  
          if(xml != null)
          {
              foreach(System.Xml.Linq.XElement currentElement in xml.Elements())
              {
                  switch (currentElement.Name.LocalName)
                  {
                      case "userSettings":
                      case "applicationSettings":
                          foreach (System.Xml.Linq.XElement settingNamespace in currentElement.Elements())
                          {
                              if (settingNamespace.Name.LocalName == "SnipetTester.Properties.Settings")
                              {
                                  foreach (System.Xml.Linq.XElement setting in settingNamespace.Elements())
                                  {
                                      LoadSetting(setting);
                                  }
                              }
                          }
                          break;
                      default:
                          break;
                  }
              }
          }
      }
  
      //Loads a setting based on it's xml representation in the config file
      private void LoadSetting(System.Xml.Linq.XElement setting)
      {
          string name = null, type = null, value = null;
  
          if (setting.Name.LocalName == "setting")
          {
              System.Xml.Linq.XAttribute xName = setting.Attribute("name");
              if (xName != null)
              {
                  name = xName.Value;
              }
  
              System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs");
              if (xSerialize != null)
              {
                  type = xSerialize.Value;
              }
  
              System.Xml.Linq.XElement xValue = setting.Element("value");
              if (xValue != null)
              {
                  value = xValue.Value;
              }
          }
  
  
          if (string.IsNullOrEmpty(name) == false &amp;&amp;
              string.IsNullOrEmpty(type) == false &amp;&amp;
              string.IsNullOrEmpty(value) == false)
          {
              switch (name)
              {
                  //One of the pitfalls is that everytime you add a new
                  //setting to the config file, you will need to add another
                  //case to the switch statement.
                  case "SettingSomething":
                      this[name] = value;
                      break;
                  default:
                      break;
              }
          }
      }
  }
  </code></pre>
  
  <p>The code I added exposes an <code>Properties.Settings.Load(string filename)</code> function.  The function accepts a config filename as a parameter.  It will parse the file and load up any settings it encounters in the config file.  To revert back to the original configuration, simply call <code>Properties.Settings.Reload()</code>.</p>
  
  <p>Hope this might help someone else!</p>