如何动态地加载一个独立的应用程序设置文件,并与当前设置合并?并与、应用程序、加载、独立

2023-09-02 10:30:49 作者:泪干了,梦也该醒了

有关于从一个单独的配置文件 阅读设置问题,并其他类似的话,但我的问题是特定于应用程序的属性设置(即< MyApplication.Properties.Settings> - 见下面的XML文件),以及如何动态地加载它们。我试图在这个帖子,其中涉及刷新主配置文件的完整的appSettings节,但我适应抛出异常,因为我并没有更换appSettings部分:

There are questions pertaining to reading settings from a separate config file and others similar to it, but my question is specific to application property settings (i.e. <MyApplication.Properties.Settings> - see XML file below) and how to load them dynamically. I tried the method in this post, which involved refreshing the entire appSettings section of the main config file, but my adaptation threw exceptions because I wasn't replacing the appSettings section:

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
// Have tried the other ConfigurationUserLevels to no avail
config.AppSettings.File = myRuntimeConfigFilePath;
config.Save(ConfigurationSaveMode.Modified); // throws ConfigurationErrorsException
ConfigurationManager.RefreshSection("userSettings");

该ConfigurationErrorsException.Message是根元素必须在节的名称相匹配引用文件的appSettings(C: myfile.xml中第2行)。该文件是:

The ConfigurationErrorsException.Message is "The root element must match the name of the section referencing the file, 'appSettings' (C:myFile.xml line 2)." The file is:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <MyApplication.Properties.Settings>
            <setting name="SineWaveFrequency" serializeAs="String">
                <value>6</value>
            </setting>
            <setting name="SineWaveAmplitude" serializeAs="String">
                <value>6</value>
            </setting>
        </MyApplication.Properties.Settings>
    </userSettings>
</configuration>

有没有办法从这个文件中导入值到 MyApplication.Properties.Settings.Default 类,以处理所有的XML序列化像它在框架配置文件被装载在应用程序启动?

Is there a way to import the values from this file into the MyApplication.Properties.Settings.Default class, with the framework handling all XML deserialization like it does when the config file is loaded on application startup?

推荐答案

那么,这个作品:

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>

导入方法解析该文件,占用了节点内,提出了XML转换的相应部分的user.config文件,然后重新加载Properties.Settings.Default,以便从该新用户抓住这些值。配置文件。

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.