在 Winforms 中保存/恢复多个设置文件

Posted

技术标签:

【中文标题】在 Winforms 中保存/恢复多个设置文件【英文标题】:Saving/Restoring multiple settings files in Winforms 【发布时间】:2021-04-21 14:02:25 【问题描述】:

我在 WinForms 应用程序的 Properties 文件夹中有 3 个设置文件。它们是默认设置、工具和车辆。设置一切正常。

我使用以下代码从 user.config 中导出设置:

internal static void Export(string settingsFilePath)

    Properties.Settings.Default.Save();
    var config = configurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
    config.SaveAs(settingsFilePath);

然后恢复:

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
    

我想要做的只是提取,例如,仅部分 Properties.Vehicle.Default 设置并更新 user.config 仅更改 sectionGroup“userSettings”的该部分。目的是保存载具加载其设置以供使用 - 但不更改设置或工具设置。

<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="Drive.Properties.Tool" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    <section name="Drive.Properties.Vehicle" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    <section name="Drive.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />

但是代码行:

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

只允许我隔离用户设置,以便加载所有部分并覆盖用户配置。段名我试过了,但由于不是组,所以返回为null。

那么有什么方法可以指定从我导出的 xml 文件中的 sectionGroup 中仅提取其中一个部分,并仅更新 user.config 并仅使用该部分而不影响其他部分?

我离得很近——但还不够近。谢谢。

【问题讨论】:

【参考方案1】:

假设你有SettingsA.settingsSettings.Settings三个设置:

这些设置的默认值将存储为应用程序配置文件 (&lt;YourAppName&gt;.exe.config) 中应用程序文件旁边的 userSettings 部分组的部分。

这些设置的用户值将作为userSettingsd 部分组的部分存储在user.config 文件中的%userprofile%\appdata\local\&lt;YourAppName&gt;\&lt;Hash&gt;\&lt;Version&gt; 中。

以下代码将所有当前用户配置保存到一个文件中,包括 SettingsA 和 Settings.这基本上就像复制包含当前用户值的user.config 文件:

ConfigurationManager
    .OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
    .SaveAs(path);

以下代码将仅从您使用上述代码创建的备份文件中恢复 SettingsA

var config = ConfigurationManager
   .OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
string sectionName = Properties.SettingsA.Default.Context["GroupName"].ToString();
var document = XDocument.Load(Path.Combine(Application.StartupPath, path));
var settingsA = document.XPathSelectElements($"//sectionName")
    .Single().ToString();
config.GetSectionGroup("userSettings")
    .Sections[sectionName].SectionInformation.SetRawXml(settingsA);
config.Save(ConfigurationSaveMode.Modified);
Properties.SettingsA.Default.Reload();

【讨论】:

别被Setting.settings文件搞糊涂了,它不是特殊文件,只是设置文件之一,和SettingsA.settings很像 按要求工作。太感谢了。获取 sectionName 作为选择是文档仅修复 user.config 中的一个部分的技巧 知道配置设置如何知道何时使用默认设置文件或使用配置吗?仅仅是 user.config 中有一个节点吗?即使还原将这些元素添加到几乎为空的 user.config,它也可以工作并使用还原的设置。这是一个非常聪明的系统。 对于用户设置,它首先在%userprofile%\appdata\local\&lt;YourAppName&gt;\&lt;Hash&gt;\&lt;Version&gt; 中查找user.config 文件,然后在您的应用程序文件旁边的&lt;YourAppName&gt;.exe.config 中查找,然后进入属性的DefaultSettingValueAttribute

以上是关于在 Winforms 中保存/恢复多个设置文件的主要内容,如果未能解决你的问题,请参考以下文章

.NET 5 WinForms 应用程序中保存的设置在哪里?

保存和恢复表格位置和大小

在 .NET Winforms 应用程序中保存设置 [重复]

如何在文件管理器中保存多个图像

c# winforms如何保存用户输入的数据

如何在 WinForms 运行时设置多个按钮文本?