How to load a separate Application Settings file dynamically and merge with current settings?

Well, this works:

using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;

public static class SettingsIO
{
    internal static void Import(string settingsFilePath)
    {
        if (!File.Exists(settingsFilePath))
        {
            throw new FileNotFoundException();
        }

        var appSettings = Properties.Settings.Default;
        try
        {
            var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);

            string appSettingsXmlName = 
Properties.Settings.Default.Context["GroupName"].ToString(); 
// returns "MyApplication.Properties.Settings";

            // Open settings file as XML
            var import = XDocument.Load(settingsFilePath);
            // Get the whole XML inside the settings node
            var settings = import.XPathSelectElements("//" + appSettingsXmlName);

            config.GetSectionGroup("userSettings")
                .Sections[appSettingsXmlName]
                .SectionInformation
                .SetRawXml(settings.Single().ToString());
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("userSettings");

            appSettings.Reload();
        }
        catch (Exception) // Should make this more specific
        {
            // Could not import settings.
            appSettings.Reload(); // from last set saved, not defaults
        }
    }

    internal static void Export(string settingsFilePath)
    {
        Properties.Settings.Default.Save();
        var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
        config.SaveAs(settingsFilePath);
    }
}

The export method creates a file like the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <MyApplication.Properties.Settings>
            <setting name="SineWaveFrequency" serializeAs="String">
                <value>1</value>
            </setting>
            <setting name="SineWaveAmplitude" serializeAs="String">
                <value>100</value>
            </setting>
            <setting name="AdcShift" serializeAs="String">
                <value>8</value>
            </setting>
            <setting name="ControlBitsCheckedIndices" serializeAs="String">
                <value>0,1,2,3,5,6,7,8</value>
            </setting>
            <setting name="UpgradeSettings" serializeAs="String">
                <value>False</value>
            </setting>
        </MyApplication.Properties.Settings>
    </userSettings>
</configuration>

The import method parses that file, takes the everything inside the node, puts that XML into the user.config file at the appropriate section, then reloads the Properties.Settings.Default in order to grab those values from the new user.config file.

Leave a Comment