何时以及为什么应该将数据存储在Windows注册表中?

136
作为一名开发人员,将配置/选项存储在注册表中的工具是我的噩梦。我无法轻松跟踪这些选项的更改,也不能轻松地将它们从一台机器移植到另一台机器上,这让我真的很怀念旧时代的.INI文件...
当编写自己的应用程序时,我应该选择将什么内容放入注册表而不是老式的配置文件中,为什么?

我现在正在使用一个遗留的应用程序,它将信息存储在注册表中(.NET 应用程序),让我感到很恼火。 - George Stocker
14个回答

81
  • 原始配置(WIN3)存储在Windows目录下的WIN.INI文件中。
  • 问题:WIN.INI变得太大。
  • 解决方案(Win31):在程序所在目录中使用各自的INI文件。
  • 问题:该程序可能安装在网络上并由多个人共享。
  • 解决方案(Win311):在用户的Window目录中使用各自的INI文件。
  • 问题:许多人可能共享一个Windows文件夹,而且应该是只读的。
  • 解决方案(Win95):注册表为每个用户分别设置不同的部分。
  • 问题:注册表变得太大。
  • 解决方案(WinXP):将大块的个人数据移至用户自己的应用数据文件夹中。
  • 问题:适合大量数据,但对于小量数据而言过于复杂。
  • 解决方案(.NET):在与应用程序相同的文件夹中使用.config (Xml)文件存储少量的固定、只读数据,并提供API来读取它。(读/写或用户特定数据保留在注册表中)

20
Unix:配置存储在$HOME/.your-app中。 一次迭代解决。 - Leonel
37
Unix的解决方案也远非理想:$HOME目录被点文件填满,而且大多数文件的作用你并不清楚。 - Maxim Razin
3
@Leonel XDG 实际上要求将配置文件放在 $HOME/.config/your-app/ 中,这是为了解决 @grep 指出的问题而创建的一种解决方案。而且,令人惊讶的是,现代 Linux(以及任何使用 GNOME 的 *BSD 用户)也在 gconf 套件中拥有注册表。自由开源软件肯定会带来选择。 ;) - new123456
2
@grep,Re“no idea what most of them do”,为什么不呢?此外,这种膨胀与Windows的膨胀几乎无法比较。 - Pacerier

19

从用户和程序员的角度来看,除了文件关联或机器特定设置之类的东西外,我认为没有好的理由将某些内容放入注册表中。

我来自这样一个思想的学派:程序应该可以在安装任何位置上运行,在机器内部完全可移动,甚至移到另一台机器上也不会影响其运行。

任何可配置选项或所需的DLL等,如果它们不是共享的,应该位于安装目录的子目录中,以便整个安装可以轻松移动。

我使用许多像是实用程序一样的小型程序,因此,如果不能在USB存储设备上安装并插入到另一台机器上并直接运行,则对我而言这不是一个好的选择。


4
安装通常在管理员控制下完成,而更新设置必须在用户控制下完成。想象一下尝试更新设置 - 在用户身份下运行的应用程序想要写入仅限管理员访问的目录。这是注册表旨在解决的问题之一。 - Cheeso
@Cheeso,解决方案是每个用户都拥有可执行文件的副本。为了节省空间,不是真正的副本,而只是一个虚假的副本(指针)。 - Pacerier
说一个程序应该能够从安装的任何位置运行,安装应该在机器内部完全可移动,甚至可以移动到另一台机器上而不影响其运行。告诉这个给 flatpak 用户 :) - SinaMobasheri

14

何时使用 - 当你被迫与传统集成或因为客户的系统管理员说“必须如此”或者因为你正在开发一种较旧的语言而使得使用XML更加困难时。

为什么使用 - 主要是因为注册表不像将配置文件复制到应用程序旁边那样易于移植(并且几乎叫相同的名称)。

如果你使用的是.NET 2+,则拥有App.Config和User.Config文件,您不需要在注册表中注册DLL,因此请避免使用它。

配置文件也有其自身的问题(请参见下文),但是这些问题可以编码解决,并且您可以修改您的架构。

  • 问题:应用程序需要可配置的设置。
  • 解决方案:在Windows文件夹中的文件(WIN.INI)中存储设置 - 使用部分标题来组织数据(Win3.0)。
  • 问题:WIN.INI文件变得太大(而且变得混乱)。
  • 解决方案:在与应用程序相同的文件夹中的INI文件中存储设置(Win3.1)。
  • 问题:需要用户特定的设置。
  • 解决方案:在用户的Window目录中以用户特定的INI文件存储用户设置(Win3.11)或在应用程序INI文件中存储用户特定的部分。
  • 问题:安全性 - 一些应用程序设置需要只读。
  • 解决方案:具有安全性以及用户特定和机器范围部分的注册表(Win95)。
  • 问题:注册表变得太大。
  • 解决方案:用户特定的注册表移动到用户自己的“应用程序数据”文件夹中的user.dat,并且仅在登录时加载(WinNT)。
  • 问题:在大型企业环境中,您要登录多台计算机并且必须对每个计算机进行设置。
  • 解决方案:区分本地(Local Settings)和漫游(Application Data)配置文件(WinXP)。
  • 问题:无法像.NET的其他部分那样使用xcopy部署或移动应用程序。
  • 解决方案:在与应用程序相同的文件夹中使用APP.CONFIG XML文件-易于阅读、易于操作、易于移动、可以跟踪是否更改(.Net1)。
  • 问题:仍需要以类似的(即xcopy deploy)方式存储特定于用户的数据。
  • 解决方案:在用户本地或漫游文件夹中使用USER.CONFIG XML文件,并进行强类型化(.Net2)。
  • 问题:CONFIG文件区分大小写(对人来说不直观),需要非常特定的开放/关闭“标记”,连接字符串无法在运行时设置,安装程序不能像注册表一样轻松地编写设置,无法轻松确定user.config文件并且每次安装新版本都会重置用户设置。
  • 解决方案:使用ITEM成员在运行时设置连接字符串,在Installer类中编写代码以在安装期间更改App.Config,并将应用程序设置用作默认值,如果找不到用户设置,则使用默认设置。

  • 这个答案比批准的答案更完整。谢谢@AndrewD。 - rotman

    13

    微软政策:

    • 在 Windows 95 之前,我们使用 ini 文件存储应用程序数据。
    • 在 Windows 95 到 XP 时代,我们使用注册表。
    • 从 Windows Vista 开始,我们使用基于 xml 的 ini 文件。

    注册表是与机器相关的。我从来都不喜欢它,因为它越来越慢,几乎不可能找到你需要的东西。这就是为什么我喜欢简单的 ini 或其他设置文件。你知道它们在哪里(应用程序文件夹或用户文件夹),所以它们易于移植和阅读。


    2
    你能提供一份原始链接,证明微软公司的这项政策吗?当你说政策时,是指微软公司的做法,还是指微软公司建议为Windows构建应用程序的开发人员应该遵循的规定? - Cheeso
    1
    PS:微软的雷蒙德·陈(Raymond Chen)已经指出,INI文件已被注册表所取代,并解释了原因。 http://blogs.msdn.com/oldnewthing/archive/2007/11/26/6523907.aspx 他还指出,XML文件与ini文件有许多相同的缺点。 - Cheeso
    8
    XML设置文件 = 难以解析的INI文件。 - Robert Fraser
    3
    如果你认为解析 XML 很困难,那么你可能不适合从事这个行业。 - SnakeDoc
    @SnakeDoc,更困难并不意味着更难。它只是意味着解析速度更慢和延迟更高。 - Pacerier
    显示剩余3条评论

    9

    如果你在Windows注册表中存储了一些窗口位置和最近使用的项目清单,世界会毁灭吗?这对我来说一直都很好。

    HKEY-CURRENT-USER是一个非常适合存储少量用户数据的好地方。这就是它的用途。因为其他人滥用了它,所以不使用它的本意似乎有点愚蠢。


    7

    注册表的读写是线程安全的,但文件不是。因此,这取决于您的程序是否单线程。


    4

    如果您希望在用户的漫游配置文件中使用的设置可用,那么最好将其放在注册表中,除非您真的想手动查找用户的应用程序数据文件夹。


    3
    如果您正在开发一款新的应用程序并且关心可移植性,那么您应该绝不将数据存储在Windows注册表中,因为其他操作系统没有(Windows)注册表(duh注释-这可能很明显,但经常被忽视)。
    如果您只是针对Win平台进行开发...请尽量避免使用它。配置文件(可能加密)是更好的解决方案。将数据存储到注册表中没有任何好处 - (例如,如果您正在使用.NET,则孤立存储是一个更好的解决方案)。

    这部分是正确的。Mono已经实现了Microsoft.win32命名空间用于注册表 - 除了它将其存储在一个xml文件中的~/.mono/Registry文件中,并且它被透明地处理。现在,如果您可以为任何应用程序打开xml处理功能,而不考虑平台... - Robert P
    注意:仅当您编写.NET/Mono应用程序时才可用。 - Robert P
    1
    注册表确实带来了好处:在多线程应用程序中,数据更容易访问。更重要的是,它允许您区分机器特定和用户特定的配置数据。当访问HKEY_CURRENT_USER时,您的应用程序不必知道谁已登录。不过,您对可移植性的看法是正确的。 - James

    2
    略微偏题,但是我发现有人关心可移植性,我使用过的最好的方法是Qt的QSettings类。它抽象了设置的存储(Windows上的注册表,Mac OS上的XML首选项文件和Unix上的Ini文件)。作为该类的客户端,我不必花费大脑去考虑注册表或其他任何东西,它只需要正常工作 (tm)。 http://doc.trolltech.com/4.4/qsettings.html#details

    似乎该URL不再起作用。更新参考应为http://qt-project.org/doc/qt-5/QSettings.html#details。 - Eineki

    1

    个人而言,我曾使用注册表来存储安装路径,以供(卸载)脚本使用。我不确定这是否是唯一的可行选项,但似乎是一个明智的解决方案。当然,这是针对仅在 Windows 上使用的应用程序。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接