如何保存应用程序设置在一个窗户的形式应用程序?
-
19-08-2019 - |
题
什么我想要实现非常简单:我有一个窗形式(.净3.5)应用程序使用的路径读取信息。这个路径可能由用户修改,通过使用所选择的形式,我提供的。
现在,我想保存的道路的价值到一文件,供以后使用。这将是一个许多设置保存的该文件。这个文件将直接坐在应用程序的文件夹。
我了解三个选项可供选择:
- 配置的设置里读取这些文件(称.exe。config)
- 注册
- 定义XML文件
我读了.净额结构的文件不是预计节省值。作为对注册表,我希望得到远离它作为可能。
这是不是意味着我应该用一个自定义用XML文件保存配置的设置?如果是这样,我希望看到码的例子,(C#)。
我已经看到其他关于这一问题的讨论,但它仍然不清楚我。
解决方案
如果你的工作与Visual Studio然后这是很容易得到持久的设置。右击该项目在解决方案资源管理器,选择性。选择设置标签,点击的链接,如果设置不存在。使用的设置标签,以创建的应用程序的设置。Visual Studio创建文件 Settings.settings
和 Settings.Designer.settings
包含单独的类 Settings
继承了 ApplicationSettingsBase.你可以访问这类代码阅读写的应用程序的设置:
Properties.Settings.Default["SomeProperty"] = "Some Value";
Properties.Settings.Default.Save(); // Saves settings in application configuration file
这一技术可适用的两台,Windows形式和其它项目类型。
注意,需要设置 范围 酒店的设置。如果你选择的应用范围,然后设置。默认。< 你的酒店>将只读。
其他提示
如果你正在计划保存一个文件在同一个目录作为可执行的,这是一个很好的解决方案的使用 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.json";
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;
}
}
}
登记是一个没有去。你不肯定的用户是否使用你的申请,有足够的权利写入注册表。
你可以使用 app.config
文件保存应用程序级别的设置(相同的每个用户使用应用程序)。
我将存储用户的具体设置在XML文件,它将被保存在 孤立存 或 SpecialFolder.ApplicationData 目录。
下一步是,作为。网2.0的,它能够储存值回来的 app.config
文件。
的 ApplicationSettings
类不支持节能设置的应用程序。配置文件。这是非常由设计、运行的应用程序与适当地固定用户账户(认为Vista UAC)没有写入该程序的安装的文件夹。
你可以打这个系统的 ConfigurationManager
类。但是琐碎的解决方法是进入设置的设计和改变设定的范围。如果这一困难的原因(譬如说,设置相关的每一个用户),你应该把你的选择功能在一个单独的程序,所以你可以要求的权限提升提示。或者放弃使用设置。
注册/配置的设置里读取这些/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) { }
}
}
}
我想分享一个图书馆我已经建立了这一点。这是一个微小的图书馆,但一个很大的改进(恕我直言)。设置文件。
库被称为 记(审查), ,这里是一个古老的 代码项目的文章 我写了关于它。
这里的你如何用它来跟踪的一个窗的大小和位置:
public MainWindow()
{
InitializeComponent();
_stateTracker.Configure(this)
.IdentifyAs("MyMainWindow")
.AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
.RegisterPersistTrigger(nameof(Closed))
.Apply();
}
利益相比。设置文件: 还有大大减少代码,这是个很不容易出错,因为你只需要提到的每个酒店 一旦.
与设置的的文件需要提及每个酒店 五个 时间:一旦当你建立明确的财产,并增加四倍,在代码复制的价值观来回。
存储、化,等等。是完全可配置的。当目标对象是创建一个IOC容器,可以[hook it up][]使其适用自动跟踪所有对象的解决,以便所有你需要做一个酒店的持久性是打一个[可跟踪的]属性。
这是非常可配置的,你可以配置:-当的数据是持久的,并应用于全球或每个追踪对象 -它是如何化 -它在哪里存放(例如文件、数据库、在线的、孤立的储存、注册) -规则,可以取消申请/数据保持一个酒店
相信我,图书馆是顶尖!
一个简单的方法是使用数据配置的目的,保存它作为一种XML文件的应用程序的名称在当地的文件夹,在启动时阅读它。
这里是一个例子存储位置和大小的形式。
的配置数据对象是强类型和易于使用:
[Serializable()]
public class CConfigDO
{
private System.Drawing.Point m_oStartPos;
private System.Drawing.Size m_oStartSize;
public System.Drawing.Point StartPos
{
get { return m_oStartPos; }
set { m_oStartPos = value; }
}
public System.Drawing.Size StartSize
{
get { return m_oStartSize; }
set { m_oStartSize = value; }
}
}
一个管理类保存和装载:
public class CConfigMng
{
private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
private CConfigDO m_oConfig = new CConfigDO();
public CConfigDO Config
{
get { return m_oConfig; }
set { m_oConfig = value; }
}
// Load configuration file
public void LoadConfig()
{
if (System.IO.File.Exists(m_sConfigFileName))
{
System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
Type tType = m_oConfig.GetType();
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
object oData = xsSerializer.Deserialize(srReader);
m_oConfig = (CConfigDO)oData;
srReader.Close();
}
}
// Save configuration file
public void SaveConfig()
{
System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
Type tType = m_oConfig.GetType();
if (tType.IsSerializable)
{
System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
xsSerializer.Serialize(swWriter, m_oConfig);
swWriter.Close();
}
}
}
现在,您可以创建一个实例,并使用在形成的负载和关闭事件:
private CConfigMng oConfigMng = new CConfigMng();
private void Form1_Load(object sender, EventArgs e)
{
// Load configuration
oConfigMng.LoadConfig();
if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
{
Location = oConfigMng.Config.StartPos;
Size = oConfigMng.Config.StartSize;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// Save configuration
oConfigMng.Config.StartPos = Location;
oConfigMng.Config.StartSize = Size;
oConfigMng.SaveConfig();
}
和生产XML文件也是阅读:
<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<StartPos>
<X>70</X>
<Y>278</Y>
</StartPos>
<StartSize>
<Width>253</Width>
<Height>229</Height>
</StartSize>
</CConfigDO>
我不喜欢所提出的解决方案的使用 web.config
或 app.config
.试着读你自己的XML。看看 XML设置文件–没有更多的网络。config.
其他的选择,而不是使用定义XML文件,我们可以使用一个更友好的用户文件的格式:JSON或其文件。
- 如果您使用。净4.0动态,这种图书馆是很容易使用 (serialize,deserialize、嵌套的对象支持并排出 如你所愿+合并多个设置的一个) JsonConfig (使用相当于ApplicationSettingsBase)
- 为。净其结构图书馆...我还没有找到一样 容易使用,因为JsonConfig
你可以存储设置文件的多个特别的文件夹(为所有用户和每个用户)作为列在这里 环境。SpecialFolder枚举 和多文件(默认只读每个角色,每个用户,等等。)
- 样品中获取的道路的特别文件夹: C#让路 %应用程序数据%
如果你选择使用多种设置,可以合并这些设置:例如,合并设置默认+BasicUser+AdminUser.你可以用你自己的规则:最后一个复盖值,等等。
"这是不是意味着我应该用一个自定义用XML文件保存配置的设置?" 不,不一定。我们使用SharpConfig为这样的行动。
例如,如果配置文件就是这样
[General]
# a comment
SomeString = Hello World!
SomeInteger = 10 # an inline comment
我们可以检索的数值喜欢这个
var config = Configuration.LoadFromFile("sample.cfg");
var section = config["General"];
string someString = section["SomeString"].StringValue;
int someInteger = section["SomeInteger"].IntValue;
这是兼容的。网2.0和高。我们可以创建配置文件和我们可以保存它。资料来源: http://sharpconfig.net/ 审查: https://github.com/cemdervis/SharpConfig
我希望这有所帮助。
我可以告诉,.网络的支持,持续存在的设置使用的内应用程序设置的设施:
该应用程序的设置特征的Windows的形式使它容易创造、存储和维护定制应用程序和用户喜好的客户的计算机。Windows形式应用程序设置的,你不仅可以存储数据的应用(如数据库连接串用,也方便用户的具体数据,例如用户应用程序的偏好。使用Visual Studio或定制的管理代码,可以创建新的设置,他们读写到磁盘,将它们绑定要属性形式,并验证设置数据之前装载和保存。- http://msdn.microsoft.com/en-us/library/k4s6c3a0.aspx
有时候,你想摆脱这些设置保持在传统的网络。配置或应用程序。配置文件。你想要的更多细控制的部署设置的项目和分离数据的设计。或者要求是为了使增加新的条目运行时间。
我可以想象一下两个很好的选择:
- 强类型版本和
- 面向对象的版本。
利用强类型的版本的强烈类型设置的名称和价值观。没有风险的相互混合的名称或数据类型。缺点是,更多的设置必须编码,无法加入在运行时间。
与面向对象的版本优点是,新设置,可以添加在运行时间。但你没有强类型的名称和价值观。必须小心用字符串标识符。必须知道数据的类型之前保存时得到的价值。
你可以找到代码的两个功能齐全的实现 在这里,.
public static class SettingsExtensions
{
public static bool TryGetValue<T>(this Settings settings, string key, out T value)
{
if (settings.Properties[key] != null)
{
value = (T) settings[key];
return true;
}
value = default(T);
return false;
}
public static bool ContainsKey(this Settings settings, string key)
{
return settings.Properties[key] != null;
}
public static void SetValue<T>(this Settings settings, string key, T value)
{
if (settings.Properties[key] == null)
{
var p = new SettingsProperty(key)
{
PropertyType = typeof(T),
Provider = settings.Providers["LocalFileSettingsProvider"],
SerializeAs = SettingsSerializeAs.Xml
};
p.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
var v = new SettingsPropertyValue(p);
settings.Properties.Add(p);
settings.Reload();
}
settings[key] = value;
settings.Save();
}
}