如何使用.NET配置文件(app.config,settings.settings)来保存和恢复所有应用程序数据?

时间:2009-12-08 20:31:20

标签: .net configuration import export configuration-files

虽然有很多关于.net配置文件的帖子,但我相信我的要求不允许提出任何解决方案(或者我不理解这个过程对我有用)。

情况是我有一个Windows窗体应用程序(也可能是另一个应用程序),它将某些用户输入字段(例如IP地址)以及表单属性(窗口大小等)绑定到应用程序设置(在属性 - >设置区域)。据我所知,这些设置与我项目的app.config文件中的设置相同,所以我应该能够使用System.Configuration.ConfigurationManager类来操作这些设置。

我想要做的是允许用户导出和导入所有已保存的设置。我没有对某些自定义对象进行序列化或使用INI文件,而是认为保存和替换应用程序使用的配置文件会更容易。

将当前设置保存到指定文件相对容易:

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

但是,恢复配置文件以覆盖当前设置很困难。 好像我可以打开像这样的配置文件

var newConfig = ConfigurationManager.OpenExeConfiguration(settingsFilePath)

但是我没有看到如何将当前配置中的所有设置完全替换为导入文件的设置。 [编辑:此重载应该接收路径.exe文件,而不是.config文件。如果调用代码未在配置文件中引用相同的程序集,则以这种方式打开exe文件可能会抛出ConfigurationErrorsException。]

也许我只需要使用other posts中列出的方法来仅替换配置的一部分,而不是整个部分,但我不知道在这一点上它是如何工作的。

有什么想法吗?我是走正确的轨道,还是应该只使用INI文件(或其他东西)?

5 个答案:

答案 0 :(得分:3)

由于app.config文件是一个简单的xml文件,您可以将其加载到XDocument中:

string path = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
XDocument doc = XDocument.Load(path);
//Do your modifications to section x
doc.Save(path);
ConfigurationManager.RefreshSection("x");

我根据@Pat的评论

更正了XDocument.Load()代码

答案 1 :(得分:3)

最佳做法是不写入app.config,而是使用设置文件保存修改后的用户设置。 app.config和web.config只能用于只读值。

答案 2 :(得分:2)

由于我没有收到任何其他答案,并且对我以前的解决方案不满意,我再次提出问题,做了一些更多的研究,并且能够得到更好的答案。有关代码和说明,请参阅How to load a separate Application Settings file dynamically and merge with current settings?

答案 3 :(得分:1)

我不认为覆盖整个配置文件是个好主意。此文件中的某些设置可能包含在您的任何代码有机会执行任何操作(即与.NET CLR启动相关的操作)之前要尽早处理的设置。

答案 4 :(得分:0)

感谢Manu建议将文件作为XML读取,我一起攻击this solution。 (它仅适用于保存为字符串的属性的当前形式,例如TextBox的Text属性。例如,如果您持久保存NumericUpDown控件的Value属性,它将无法工作。)它的工作方式是使用Export with要保存的文件的路径,它生成如下文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <HawkConfigGUI.Properties.Settings>
            <setting name="FpgaFilePath" serializeAs="String">
                <value>testfpga</value>
            </setting>
            <setting name="FirmwareFilePath" serializeAs="String">
                <value>test</value>
            </setting>
        </HawkConfigGUI.Properties.Settings>
    </userSettings>
</configuration>

然后导入文件并在应用程序中更改所有设置(不要忘记在某些时候使用.Save())。如果出现问题,设置将恢复。

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

namespace HawkConfigGUI
{
    public static class SettingsIO
    {
        private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

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

            var appSettings = Properties.Settings.Default;
            try
            {
                // Open settings file as XML
                var import = XDocument.Load(settingsFilePath);
                // Get the <setting> elements
                var settings = import.XPathSelectElements("//setting");
                foreach (var setting in settings)
                {
                    string name = setting.Attribute("name").Value;
                    string value = setting.XPathSelectElement("value").FirstNode.ToString();

                    try
                    {
                        appSettings[name] = value; // throws SettingsPropertyNotFoundException
                    }
                    catch (SettingsPropertyNotFoundException spnfe)
                    {
                        _logger.WarnException("An imported setting ({0}) did not match an existing setting.".FormatString(name), spnfe);
                    }
                    catch (SettingsPropertyWrongTypeException typeException)
                    {
                        _logger.WarnException(string.Empty, typeException);
                    }
                }
            }
            catch (Exception exc)
            {
                _logger.ErrorException("Could not import settings.", exc);
                appSettings.Reload(); // from last set saved, not defaults
            }
        }

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