以 .NET 的方式处理应用程序设置。INI、注册表或 XML






4.61/5 (87投票s)
在本文中,我将解释如何仅用几行代码轻松存储和检索您的应用程序设置
引言
.NET 应用程序通常已不再使用 INI 文件和注册表。但该用什么呢?XML 似乎很合适,但仅为存储几个字段而查看一下 System.XML
就足以让大多数开发者望而却步。幸运的是,.NET 中有一种非常简单的方法可以解决这个问题,但它通常不被开发者所注意到。在本文中,我将解释如何仅用几行代码轻松存储和检索您的应用程序设置。
历史
在 Windows 3.1 中,开发人员使用 INI 文件来存储设置。总的来说,它们在处理简单设置时效果很好,但对于更复杂的数据则不适用。INI 文件也不能处理多用户的情况,因此微软发明了注册表。
随着 Win32 的出现,注册表也随之而来。注册表速度快,分层化,支持多用户,并且允许存储类型化数据。但不幸的是,注册表是一个核心系统组件,并没有包含在应用程序的安装中。
接下来,XML 流行起来。XML 提供了快速、分层化的类型化数据存储。然而,XML 的灵活性非常高,以至于对大多数用户来说,做任何简单的事情都是一项艰巨的任务。幸运的是,有比使用 System.XML
和自己处理一切更简单的方法。
旧方法
许多用户简单地诉诸使用 INI 文件或注册表。INI 文件在 .NET 中不受支持。要使用 INI 文件,开发者必须直接调用 Win32 API,或者使用 Internet 上使用 Win32 API 的一些现成类。对于注册表,Microsoft.Win32
中提供了类。然而,XML 是可移植的,并且在必要时可以轻松地由最终用户进行编辑。
如何
无痛 XML 设置文件的秘诀在于使用类型化的 DataSet
。类型化的 DataSet
实际上是一个内存中的数据集,用于处理 ADO.NET,但它们还有许多其他用途。要将类型化的 DataSet
添加到您的应用程序中,请在解决方案资源管理器中右键单击项目,然后选择“添加新项”。然后选择“DataSet”,并为数据集命名。
现在,我们在项目中有一个空的 DataSet
。为了演示,我已经创建了一个主窗体,外观如下。
我选择这些是为了演示,因为它们提供了三种数据类型供我们存储:字符串、整数和布尔值。现在,让我们围绕这些来设计我们的 DataSet
。
打开解决方案资源管理器并找到新创建的 DataSet
。
双击 Settings.xsd 时,您将看到一个如下所示的设计器
这是一个空的 DataSet
。一个 DataSet
可以包含多个表,但对于这次演示,我们只添加一个。打开工具箱,您将看到与 WinForms 或 WebForms 应用程序中通常看到的不同的项。
工具箱中有许多与 DataSet
相关的项,但根据本文的需求,我们只需要 Element
。双击 Element
将其添加到 DataSet
中。此时,DataSet
应显示如下
Element
类型对应于一个 DataTable
。我们将其命名为 Main
(将上面的高亮文本更改为 Main
)。现在,让我们输入我们想要存储的字段。完成后,Element
应显示如下
Visual Studio 现在将使用此 DataSet
为我们生成一组类供我们使用。现在,让我们看看主窗体上的“加载”和“保存”按钮。这些事件使用了 ConfigPathname
,这是一个在演示中预定义的字段。ConfigPathname
只是存储设置文件的路径和文件名。
C#
private void butnSave_Click(object sender, System.EventArgs e) {
Settings xDS = new Settings();
Settings.MainRow xRow = xDS.Main.NewMainRow();
xRow.Username = textUsername.Text.Trim();
xRow.PIN = int.Parse(textPIN.Text.Trim());
xRow.Admin = chckAdmin.Checked;
xDS.Main.AddMainRow(xRow);
xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema);
}
private void butnLoad_Click(object sender, System.EventArgs e) {
if (new FileInfo(ConfigPathname).Exists) {
Settings xDS = new Settings();
xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema);
if (xDS.Main.Rows.Count > 0) {
Settings.MainRow xRow = xDS.Main[0];
if (!xRow.IsUsernameNull()) {
textUsername.Text = xRow.Username;
}
if (!xRow.IsPINNull()) {
textPIN.Text = xRow.PIN.ToString();
}
if (!xRow.IsAdminNull()) {
chckAdmin.Checked = xRow.Admin;
}
}
}
}
Visual Basic .NET
Private Sub butnSave_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles butnSave.Click
Dim xDS As New Settings
Dim xRow As Settings.MainRow
xRow = xDS.Main.NewMainRow
xRow.Username = textUsername.Text.Trim()
xRow.PIN = Int32.Parse(textPIN.Text.Trim())
xRow.Admin = chckAdmin.Checked
xDS.Main.AddMainRow(xRow)
xDS.WriteXml(ConfigPathname, System.Data.XmlWriteMode.IgnoreSchema)
End Sub
Private Sub butnLoad_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles butnLoad.Click
If New FileInfo(ConfigPathname).Exists Then
Dim xDS As New Settings
Dim xRow As Settings.MainRow
xDS.ReadXml(ConfigPathname, System.Data.XmlReadMode.IgnoreSchema)
If xDS.Main.Rows.Count > 0 Then
xRow = xDS.Main.Rows.Item(0)
If Not xRow.IsUsernameNull() Then
textUsername.Text = xRow.Username
End If
If Not xRow.IsPINNull() Then
textPIN.Text = xRow.PIN.ToString()
End If
If Not xRow.IsAdminNull() Then
chckAdmin.Checked = xRow.Admin
End If
End If
End If
End Sub
加载 DataSet
时,有必要检查每个字段是否为 null。在我们的演示中,它们永远不会是 null,但如果您稍后添加字段,并且您的应用程序尝试加载一个用旧版本保存的文件,则字段可能会是 null。最终用户也可能直接编辑您的设置文件。在字段为 null 的情况下访问该字段将产生一个异常。
如果您运行演示,您可以输入一些测试值,然后单击“保存”。
单击“保存”后,演示将在与 .exe 相同的目录中创建一个 .settings 文件。通常,这是 bin/debug/SettingsDemo.exe.Settings。如果您打开此文件,您将看到它是一个标准的 XML 文件,并且可以轻松编辑。
<?xml version="1.0" standalone="yes"?>
<Settings xmlns="http://tempuri.org/Settings.xsd">
<Main>
<Username>Kudzu</Username>
<PIN>1234</PIN>
<Admin>true</Admin>
</Main>
</Settings>
现在,如果您再次运行应用程序,您可以单击“加载”按钮来加载这些设置。
在此演示中,我们只在 DataTable
中存储了一行。但是 DataTable
可以包含多行,而一个 DataSet
甚至可以包含多个相关或不相关的 DataTable
。
结论
XML 文件是一种广泛使用的标准,它允许轻松存储结构化的类型化数据。使用 XML 文件可以方便最终用户,甚至其他软件进行编辑。通过使用类型化的 DataSet
,您可以轻松地将您的设置存储在 XML 文件中。