53

我是一个新的 Windows 程序员,我不确定我应该在哪里存储用户可配置的应用程序设置。我了解需要为用户提供一种用户友好的方式来更改应用程序设置,例如 Edit | 设置表格或类似的。但是,在用户点击该表单上的“应用”按钮后,我应该将值存储在哪里?

在 Windows 注册表中存储设置与将它们存储在本地 INI 文件或配置文件或类似文件中的优缺点是什么?

4

13 回答 13

43

配置文件的优点:

  1. 很容易做到。不需要知道任何 Windows API 调用。你只需要知道你的编程语言的文件 I/O 接口。
  2. 便携的。如果您将应用程序移植到另一个操作系统,则无需更改设置格式。
  3. 用户可编辑。用户可以在程序执行之外编辑配置文件。

注册表的优点:

  1. 安全的。除非他/她知道 regedit,否则用户不会意外删除配置文件或损坏数据。然后用户只是在自找麻烦。
  2. 我不是专业的 Windows 程序员,但我确信使用注册表可以更轻松地执行其他 Windows 特定的事情(用户特定的设置、网络管理的东西,如组策略或其他任何东西)。

如果您只需要一种简单的方式来存储配置信息,我会推荐一个配置文件,使用 INI 或 XML 作为格式。我建议仅在您想摆脱使用注册表的特定内容时才使用注册表。

于 2008-08-09T04:51:59.773 回答
27

Jeff Atwood 有一篇很棒的文章,介绍了 Windows 的注册表以及为什么改用 .INI 文件更好。

如果将每个应用程序的设置存储在一个我可以轻松查看、操作和备份它们的地方,我的生活会轻松很多。比如说……在 INI 文件中。

  • 注册表是单点故障。这就是为什么你会发现每一个注册表编辑技巧都以一个关于如何用 regedit 破坏你的计算机的大肥尖叫免责声明开始的原因。
  • 注册表是不透明的和二进制的。尽管我不喜欢尖括号税,但至少 XML 配置文件是合理的人类可读的,并且它们允许尽可能多的评论。
  • 注册表必须与文件系统同步。删除一个应用程序而不“卸载”它,你就会留下陈旧的注册表。或者,如果应用程序的卸载程序编写不佳。文件系统不再是记录声明——它必须以某种方式与注册表保持同步。这完全违反了 DRY 原则。
  • 注册表是单片的。假设您想将应用程序移动到机器上的不同路径,甚至完全移动到不同的机器上。祝您好运,从巨大的注册表 tarball 中提取该特定应用程序的相关设置。一个给定的应用程序通常在注册表中散布着几十个设置。
于 2008-10-11T01:11:39.697 回答
5

在注册表中使用 INI 文件还有一个我没有提到的优势:如果用户使用某种基于卷/文件的加密,他们可以很容易地对 INI 文件进行加密。使用注册表可能会出现更多问题。

于 2008-08-24T14:41:15.243 回答
4

根据GetPrivateProfileString的文档,您应该使用注册表来存储初始化信息。

但是,话虽如此,如果您仍想使用 .ini 文件,并使用标准配置文件 API(GetPrivateProfileStringWritePrivateProfileString等)来访问它们,它们提供了自动提供由支持的“虚拟 .ini 文件”的内置方法注册表。双赢!

于 2008-08-09T04:54:24.090 回答
4

这里有一个类似的问题,涵盖了一些优点和缺点。

我建议不要使用注册表,除非您的应用程序绝对需要它。据我了解,由于设置文件的灵活性,微软正试图阻止使用注册表。此外,我不建议使用 .ini 文件,而是使用 .Net 的一些内置功能来保存用户/应用程序设置。

于 2008-08-09T13:03:06.803 回答
4

使用与应用程序位于同一目录中的 ini 文件,可以将其与应用程序一起备份。因此,在您重新加载操作系统后,您只需恢复应用程序目录,就可以按照您想要的方式进行配置。

于 2008-10-11T02:14:16.200 回答
3

我同意丹尼尔。如果它是一个大型应用程序,我想我会在注册表中做一些事情。如果它是一个小型应用程序,并且您希望在不制作配置表单的情况下使其某些方面可由用户配置,请快速获取 INI 文件。

我通常是这样解析的(如果.ini文件中的格式是option = value,每行1个,注释以#开头):

static void Parse()
{
    StreamReader tr = new StreamReader("config.ini");
    string line;
    Dictionary<string, string> config = new Dictionary<string, string>();

    while ((line = tr.ReadLine()) != null)
    {
        // Allow for comments and empty lines.
        if (line == "" || line.StartsWith("#"))
            continue;

        string[] kvPair = line.Split('=');

        // Format must be option = value.
        if (kvPair.Length != 2)
            continue;

        // If the option already exists, it's overwritten.
        config[kvPair[0].Trim()] = kvPair[1].Trim();
    }
}

编辑:对不起,我以为你已经指定了语言。上面的实现是在 C# 中。

于 2008-08-09T13:13:39.623 回答
2

正如 Daniel 所指出的,将配置数据存储在注册表中可以让您选择使用管理模板。也就是说,您可以定义一个管理模板,在组策略中使用它并在网络范围内管理您的应用程序的配置。根据应用程序的性质,这可能是一个很大的好处。

于 2008-08-24T09:01:31.737 回答
2

现有的答案涵盖了很多领域,但我想我会提到另一点。

我使用注册表来存储系统范围的设置。也就是说,当 2 个或更多程序需要完全相同的设置时。换句话说,多个程序共享的设置。

在所有其他情况下,我使用本地配置文件,该文件与可执行文件位于同一路径或下一层(在配置目录中)。其他答案已经涵盖了原因(便携式,可以使用文本编辑器进行编辑等)。

为什么要将系统范围的设置放入注册表?好吧,我发现如果一个设置是共享的,但你使用本地配置文件,你最终会复制设置。这可能意味着您最终需要在多个地方更改设置。

例如,假设 Program A 和 Program B 都指向同一个数据库。您可以为连接字符串设置“系统范围”的注册表设置。如果要指向不同的数据库,可以在一个地方更改连接字符串,两个程序现在都将针对另一个数据库运行。

注意 - 如果两个或多个程序不需要使用相同的值,那么以这种方式使用注册表是没有意义的。例如,程序 A 和程序 B 都需要一个可能相同但并非总是相同的数据库连接字符串。例如,我希望程序 B 现在使用测试数据库,但程序 A 应该继续使用生产数据库。

在上面的示例中,您可以有一些本地配置覆盖系统范围的设置,但对于简单的任务,它可能会开始变得过于复杂。

于 2016-01-21T10:25:44.333 回答
1

注册表针对快速访问和轻松更新进行了优化,它是执行某些特定于 Windows 的操作(例如与扩展关联)的唯一方法。您可以忽略有关删除单个目录以卸载程序的论点 - Windows Vista 不允许您修改 Program Files 目录中的文件,因此您的配置无论如何都需要进入不同的文件夹。

Windows 编程有一个通用指南——按照微软期望的方式做事,你的生活会轻松很多。

也就是说,我可以看到 INI 文件的吸引力,我不会责怪任何人考虑它。

于 2008-10-11T01:40:20.713 回答
0

ini 或配置文件有一个缺点,如果用户可以选择程序的安装位置,那就是定位它们。

于 2011-01-27T02:52:35.103 回答
0

使用注册表的另一个缺点是,如果您在 32 位和 64 位应用程序的混合环境中工作,会很痛苦,因为访问注册表的系统调用会随机(*) 添加\Wow6432Node\到您的注册表路径中,让您在调试时发疯.

(*当然不是随机的,但是很容易迷路)

于 2019-06-26T12:39:33.110 回答
0

好处:

  • 大量配置文件的替换。
  • 中心点的共同管理职能。
  • 应用程序/驱动程序几乎可以保存任何数据。
  • 与配置文件相比,甚至可以保存代码序列。
  • 访问比文件快,因为数据库是索引的。
  • 可以使用 RegMon 实用程序记录访问

缺点:

  • 在没有图形配置程序的情况下难以使用。
  • 使用注册表编辑器直接更改可能会产生不一致的状态。
  • 不完整的卸载程序会在注册表中留下“回忆” 导致问题,例如新安装。
  • 已安装的应用程序很难导出到其他 PC。
  • 长期记录不佳。
  • 专有结构,因此不适合标准 DB 访问(例如 SQL)
  • 特定于计算机,因此不能移植到其他计算机。
  • 注册表保护不足:取决于配置。
于 2021-06-03T09:41:06.947 回答