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

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

我知道有三种选择:

配置文件(appname.exe.config) 注册表 自定义XML文件

我读到。net配置文件不能将值保存回配置文件。至于注册表,我想尽量远离它。

这是否意味着我应该使用自定义XML文件来保存配置设置?

如果是这样,我想看看代码的例子(c#)。

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


当前回答

我想分享我为此建立的一个库。这是一个很小的库,但比.settings文件有很大的改进(恕我冒昧)。

这个库被称为Jot (GitHub)。这是我写的一篇关于它的旧的代码项目文章。

下面是如何使用它来跟踪窗口的大小和位置:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

与.settings文件相比的好处是:代码相当少,而且容易出错的情况也少得多,因为每个属性只需要提到一次。

对于设置文件,您需要提到每个属性五次:一次是在显式创建属性时,另外四次是在来回复制值的代码中。

存储、序列化等是完全可配置的。当目标对象由IoC容器创建时,您可以[连接它][],以便它自动应用跟踪到它所解析的所有对象,因此要使属性持久,您所需要做的就是在其上添加[Trackable]属性。

它是高度可配置的,你可以配置: -当数据被持久化并应用于全局或每个跟踪对象时 -它是如何序列化的 -存储在哪里(例如文件,数据库,在线,隔离存储,注册表) -可以取消为属性应用/持久化数据的规则

相信我,图书馆是一流的!

其他回答

我想分享我为此建立的一个库。这是一个很小的库,但比.settings文件有很大的改进(恕我冒昧)。

这个库被称为Jot (GitHub)。这是我写的一篇关于它的旧的代码项目文章。

下面是如何使用它来跟踪窗口的大小和位置:

public MainWindow()
{
    InitializeComponent();

    _stateTracker.Configure(this)
        .IdentifyAs("MyMainWindow")
        .AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
        .RegisterPersistTrigger(nameof(Closed))
        .Apply();
}

与.settings文件相比的好处是:代码相当少,而且容易出错的情况也少得多,因为每个属性只需要提到一次。

对于设置文件,您需要提到每个属性五次:一次是在显式创建属性时,另外四次是在来回复制值的代码中。

存储、序列化等是完全可配置的。当目标对象由IoC容器创建时,您可以[连接它][],以便它自动应用跟踪到它所解析的所有对象,因此要使属性持久,您所需要做的就是在其上添加[Trackable]属性。

它是高度可配置的,你可以配置: -当数据被持久化并应用于全局或每个跟踪对象时 -它是如何序列化的 -存储在哪里(例如文件,数据库,在线,隔离存储,注册表) -可以取消为属性应用/持久化数据的规则

相信我,图书馆是一流的!

一种简单的方法是使用配置数据对象,将其保存为本地文件夹中具有应用程序名称的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>

ApplicationSettings类不支持将设置保存到app.config文件中。这在很大程度上是故意的;使用安全用户帐户运行的应用程序(如Vista UAC)没有对程序安装文件夹的写访问权。

您可以使用ConfigurationManager类来对抗系统。但简单的解决方法是进入设置设计器并将设置的范围更改为User。如果这造成了困难(例如,设置与每个用户相关),则应该将Options特性放在单独的程序中,以便可以请求特权提升提示。或者放弃使用设置。

登记处是不允许的。您不确定使用您的应用程序的用户是否有足够的权限写入注册表。

您可以使用app.config文件保存应用程序级别的设置(对于使用您的应用程序的每个用户都是相同的)。

我将把特定于用户的设置存储在一个XML文件中,该文件将保存在隔离存储或SpecialFolder中。ApplicationData目录。

其次,从。net 2.0开始,可以将值存储回app.config文件。

“这是否意味着我应该使用自定义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;

它与。net 2.0及更高版本兼容。我们可以动态地创建配置文件,并在以后保存它。

来源:http://sharpconfig.net/ GitHub: https://github.com/cemdervis/SharpConfig