我是一名新的 Windows 程序员,我不确定应该在哪里存储用户可配置的应用程序设置。我了解需要为用户提供用户友好手段更改应用程序设置,例如编辑|设置形式或类似。但是,当用户点击该表单上的“应用”按钮后,我应该将这些值存储在哪里?

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

有帮助吗?

解决方案

配置文件的优点:

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

注册表的优点:

  1. 安全的。除非用户了解 regedit,否则用户不会意外删除配置文件或损坏数据。那么用户只是自找麻烦。
  2. 我不是专业的 Windows 程序员,但我确信使用注册表可以更轻松地执行其他特定于 Windows 的操作(特定于用户的设置、组策略等网络管理内容或其他任何操作)。

如果您只需要一种简单的方法来存储配置信息,我会推荐使用 INI 或 XML 作为格式的配置文件。我建议仅当您希望避免使用注册表时才使用注册表。

其他提示

杰夫·阿特伍德有一个伟大的 文章 关于 Windows 注册表以及为什么最好使用 .INI 文件。

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

  • 注册表是一个 单点故障. 。这就是为什么你会发现的每一个注册表编辑技巧都以一个大而令人尖叫的免责声明开头,告诉你如何使用 regedit 破坏你的计算机。
  • 注册表是 不透明和二进制. 。尽管我不喜欢尖括号税,但至少 XML 配置文件具有相当的人类可读性,并且它们允许您认为合适的任意数量的注释。
  • 注册表必须是 与文件系统同步. 。删除应用程序而不“卸载”它,您就会留下陈旧的注册表碎片。或者,如果应用程序的卸载程序编写得不好。文件系统不再是记录声明——它必须以某种方式与注册表保持同步。这完全违反了 DRY 原则。
  • 注册表是 整体式的. 。假设您想要将应用程序移动到计算机上的不同路径,甚至完全移动到另一台计算机。祝你好运,从巨大的注册表 tarball 中提取该特定应用程序的相关设置。给定的应用程序通常在注册表中散布着数十个设置。

根据文档 获取私有配置文件字符串, ,您应该使用注册表来存储初始化信息。

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

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

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

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

与注册表相比,使用 INI 文件还有一个我没有提到的优点:如果用户使用某种基于卷/文件的加密,他们可以很容易地加密 INI 文件。如果使用注册表,问题可能会更大。

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

我同意丹尼尔的观点。如果它是一个大型应用程序,我想我会在注册表中执行操作。如果它是一个小型应用程序,并且您希望用户可以对其某些方面进行配置而无需制作配置表单,请使用快速 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# 实现的。

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

Windows 编程有一个通用指南 - 按照 Microsoft 期望的方式做事,您的生活就会轻松很多。

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

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

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

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

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

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

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

通过上面的示例,您可以使用一些本地配置覆盖系统范围的设置,但对于简单的任务来说,它可能会变得过于复杂。

ini 或配置文件有一个缺点,即如果用户可以选择程序的安装位置,则无法找到它们。

您的应用程序是通过安装程序安装的,还是只是“解压并运行”?对于第一种情况,请查看此处概述的优缺点。但对于提取并运行,我认为注册表是“不行的”,因为人们希望能够简单地删除应用程序文件夹来摆脱你的程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top