CSharp - 一个Windows Forms Application最好的保存应用程序设置方式

  显示原文与译文双语对照的内容

我想要实现的非常简单: 我有一个 Windows 窗体 (.NET 3.5 ) 应用程序,它使用一个路径来读取信息。 这里路径可以由用户修改,使用我提供的选项表单。

现在,我想将路径值保存到一个文件中以备以后使用。 这将是保存到这里文件中的许多设置之一。 这里文件将直接位于应用程序文件夹中。

我了解三个选项:

  • ConfigurationSettings文件( 。exe 。config )
  • 注册表
  • 自定义XML文件

我读取了. NET 配置文件,无法将值保存回它。 至于注册表,我想尽可能远离它。

这是否意味着我应该使用自定义的XML文件来保存配置设置? 如果是的话,我想看看( C# )的代码示例。

我曾经看到过关于这个主题的其他讨论,但我仍然不清楚。

时间:

如果你使用 Visual Studio,那么获得持久的设置很容易。 右键单击解决方案资源管理器中的项目,选择Properties属性,。 选择设置选项卡,如果设置不存在,请单击超链接。 使用设置选项卡创建应用程序设置。 Visual Studio 创建包含从 ApplicationSettingsBase 继承的singleton类 Settings的文件 Settings.settingsSettings.Designer.settings 。 你可以从代码访问此类以读取/写入应用程序设置:


Properties.Settings.Default["SomeProperty"] ="Some Value";
Properties.Settings.Default.Save();//Saves settings in application configuration file

这里技术适用于控制台,Windows 窗体和其他项目类型。

请注意,你需要设置设置的范围属性。 如果你选择了应用程序作用域,那么 Settings.Default 。 <你的属性> 将是 read-only 。

注册表是一个 no-go 。 你不确定使用应用程序的用户是否有足够的权限写入注册表。

你可以使用 app.config 文件保存application-level设置( 对使用你的应用程序的每个用户都是一样的) 。

这里会存储user-specific设置了一个XML文件,该文件会被存储在独立存储 或者在 SpecialFolder.ApplicationData 目录。

在. NET 2.0中,可以将值存储回 app.config 文件。

如果你打算保存到可执行文件所在目录中的文件,那么这里是一个使用 JSON 格式的不错的解决方案:


using System;
using System.IO;
using System.Web.Script.Serialization;

namespace MiscConsole
{
 class Program
 {
 static void Main(string[] args)
 {
 MySettings settings = MySettings.Load();
 Console.WriteLine("Current value of 'myInteger':" + settings.myInteger);
 Console.WriteLine("Incrementing 'myInteger'...");
 settings.myInteger++;
 Console.WriteLine("Saving settings...");
 settings.Save();
 Console.WriteLine("Done.");
 Console.ReadKey();
 }

 class MySettings : AppSettings<MySettings>
 {
 public string myString ="Hello World";
 public int myInteger = 1;
 }
 }

 public class AppSettings<T> where T : new()
 {
 private const string DEFAULT_FILENAME ="settings.jsn";

 public void Save(string fileName = DEFAULT_FILENAME)
 {
 File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(this));
 }

 public static void Save(T pSettings, string fileName = DEFAULT_FILENAME)
 {
 File.WriteAllText(fileName, (new JavaScriptSerializer()).Serialize(pSettings));
 }

 public static T Load(string fileName = DEFAULT_FILENAME)
 {
 T t = new T();
 if(File.Exists(fileName))
 t = (new JavaScriptSerializer()).Deserialize<T>(File.ReadAllText(fileName));
 return t;
 }
 }
}

registry/configurationSettings/XML 参数仍然非常活跃。 随着技术的进步,我已经使用了它们,但我最喜欢的是基于系统的threed,以及独立存储。

下面的示例允许将名为属性的对象存储到独立存储中的文件中。 例如:


AppSettings.Save(myobject,"Prop1,Prop2","myFile.jsn");

可以使用以下方法恢复属性:


AppSettings.Load(myobject,"myFile.jsn");

只是一个例子,不是最佳实践。


internal static class AppSettings
{
 internal static void Save(object src, string targ, string fileName)
 {
 Dictionary<string, object> items = new Dictionary<string, object>();
 Type type = src.GetType();

 string[] paramList = targ.Split(new char[] { ',' });
 foreach (string paramName in paramList)
 items.Add(paramName, type.GetProperty(paramName.Trim()).GetValue(src, null));

 try
 {
//GetUserStoreForApplication doesn't work - can't identify.
//application unless published by ClickOnce or Silverlight
 IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
 using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Create, storage))
 using (StreamWriter writer = new StreamWriter(stream))
 {
 writer.Write((new JavaScriptSerializer()).Serialize(items));
 }

 }
 catch (Exception) { }//If fails - just don't use preferences
 }

 internal static void Load(object tar, string fileName)
 {
 Dictionary<string, object> items = new Dictionary<string, object>();
 Type type = tar.GetType();

 try
 {
//GetUserStoreForApplication doesn't work - can't identify
//application unless published by ClickOnce or Silverlight
 IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForAssembly();
 using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
 using (StreamReader reader = new StreamReader(stream))
 {
 items = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(reader.ReadToEnd());
 }
 }
 catch (Exception) { return; }//If fails - just don't use preferences.

 foreach (KeyValuePair<string, object> obj in items)
 {
 try
 {
 tar.GetType().GetProperty(obj.Key).SetValue(tar, obj.Value, null);
 }
 catch (Exception) { }
 }
 }
}

我不喜欢使用 web.config 或者 app.config的建议解决方案。 尝试读取你自己的XML 。 看一下 XML设置文件- 没有更多 web.config

除了使用自定义的xml文件之外,我们还可以使用更多的用户友好文件格式: json或者yaml文件。

  • 如果你使用. NET 4.0动态,这个库真的很容易使用
    ( 序列化,反序列化,嵌套对象支持和排序输出)
    希望如此+ 6 比1 ) 合并多个设置 JsonConfig ( 用法是等价于 ApplicationSettingsBase )
  • 用于. NET yaml配置库。。 我还没有找到像JsonConfig那样容易使用的东西

你可以在多个特殊 folders(for all user, per user) 中存储你的设置文件,如 Environment.SpecialFolder 枚举和多个 files(default read only, per role, per user, etc )

如果你选择使用多个设置,你可以合并这些设置: 例如合并默认设置+ BasicUser +的设置。 你可以使用自己的规则: 最后一个替代值等。

...