什么时候-为什么-应该在Windows注册表中存储数据?


126

作为开发人员,将配置/选项存储在注册表中的工具是我一生的祸根。我无法轻松跟踪对这些选项的更改,无法轻松将它们从一台机器移植到另一台机器,这一切使我真的很想念.INI文件的美好时光...

在编写自己的应用程序时,我应该选择放入注册表而不是老式的配置文件中,如果有的话,为什么?


我现在使用的是旧版应用程序,它将信息存储在注册表(.NET应用程序)中,这使我发疯。
乔治·斯托克

Answers:


75
  • 最初(WIN3)配置存储在Windows目录的WIN.INI文件中。
  • 问题:WIN.INI变得太大。
  • 解决方案(Win31):与该程序位于同一目录中的单个INI文件。
  • 问题:该程序可能已安装在网络上,并且被许多人共享。
  • 解决方案(Win311):用户的Window目录中的单个INI文件。
  • 问题:许多人可能共享一个Windows文件夹,并且无论如何它应该是只读的。
  • 解决方案(Win95):每个用户的注册表都有单独的部分。
  • 问题:注册表太大。
  • 解决方案(WinXP):将大块的单个数据移到用户自己的Application Data文件夹中。
  • 问题:适用于大量数据,但是适用于少量数据。
  • 解决方案(.NET):少量固定,只读数据存储在与应用程序位于同一文件夹中的.config(Xml)文件中,并带有API来读取它。(读/写或用户特定数据保留在注册表中)

16
Unix:配置存储在$ HOME / .your-app中,在一次迭代中解决。
莱昂内尔

33
Unix解决方案也远非理想:$ HOME充满了点文件,您不知道它们大多数会做什么。
grep

2
@Leonel XDG实际上要求您将配置文件放入其中$HOME/.config/your-app/,这是一种用于解决问题@grep对象的解决方案。而且,令人惊讶的是,现代Linux(以及* BSD上的所有人都疯狂使用GNOME)在套件中有一个注册表gconf。FOSS会带来很多选择,这是肯定的;)
new123456

1
@grep,Re“ 不知道他们大多数人都在做什么 ”,为什么不呢?此外,膨胀几乎无法与Windows相提并论。
Pacerier's

16

从用户和程序员的角度来看,我不得不说,除非在文件关联或计算机特定设置之类的东西上,否则在注册表中放置一个东西确实不是一个很好的借口。

我来自一个流派,他说一个程序应该可以在任何安装位置运行,该安装应该可以在一台机器内甚至在另一台机器上完全移动,并且不影响其运行。

任何未共享的可配置选项或必需的dll等(如果未共享)应位于安装目录的子目录中,以便轻松移动整个安装。

我使用了许多较小的实用程序,例如程序,因此,如果无法将其安装在USB记忆棒上并插入另一台计算机上并且可以运行,那么它对我来说不适合。


4
但是安装通常是在管理员控制下完成的,而更新设置则必须在用户控制下完成。想象一下尝试更新设置-一个以用户身份运行的应用程序,该应用程序希望写入仅限于管理员访问权限的目录。这是注册表旨在解决的问题之一。
Cheeso

@Cheeso,解决方案是为每个用户拥有可执行文件的副本。为了节省空间,不是真正的副本,而是伪造的副本(指针)。
Pacerier's

12

微软政策:

  • 在Windows 95之前,我们将ini文件用于应用程序数据。
  • 在Windows 95-XP时代,我们使用了注册表。
  • 在Windows Vista中,我们使用ini文件,尽管它们现在基于xml。

注册表取决于计算机。我从来不喜欢它,因为它变慢了,几乎不可能找到您需要的东西。这就是为什么我喜欢简单的ini或其他设置文件。您知道它们的位置(应用程序文件夹或用户文件夹),因此它们易于携带并且易于阅读。


1
您可以提供指向说明该Microsoft政策的文档的原始链接吗?当您说政策时,您是说这是Microsoft所做的,还是您对Microsoft建议为Windows开发应用程序的开发人员的建议?
Cheeso

1
ps:Microsoft的raymond Chen表示已弃用INI文件,以使用注册表,并解释了原因。blogs.msdn.com/oldnewthing/archive/2007/11/26/6523907.aspx他还指出XML文件与ini文件具有许多相同的缺点。
Cheeso

8
XML设置文件=难以解析的INI文件
Robert Fraser 2010年

3
@Fraser如果您认为解析XML很困难,那么您做错了事。
SnakeDoc

@SnakeDoc,更困难并不意味着更困难。这只是意味着解析和延迟较慢。
Pacerier's

12

何时 -由于旧式集成,或者由于客户的sysadmin说“应该如此”,或者因为您使用的是旧语言进行开发而使使用XML变得更加困难,您不得不这样做。

原因 -主要是因为注册表不像复制位于应用程序旁边的配置文件那样可移植(被称为几乎相同)。

如果您使用的是.Net2 +,则需要App.Config和User.Config文件,并且无需在注册表中注册DLL,因此请远离它。

配置文件有其自身的问题(请参阅下文),但是可以对其进行编码,并且可以更改体系结构。

  • 问题:应用程序需要可配置的设置。
  • 解决方案:将设置存储在Windows文件夹中的文件(WIN.INI)中-使用节标题对数据进行分组(Win3.0)。
  • 问题:WIN.INI文件变得太大(并且变得凌乱)。
  • 解决方案:将设置存储在与应用程序(Win3.1)相同的文件夹中的INI文件中。
  • 问题:需要用户特定的设置。
  • 解决方案:将用户设置存储在用户的Window目录(Win3.11)中特定于用户的INI文件中或应用程序INI文件中特定于用户的部分中。
  • 问题:安全性-某些应用程序设置需要为只读。
  • 解决方案:使用安全性以及用户特定部分和计算机范围的部分(Win95)进行注册表。
  • 问题:注册表太大。
  • 解决方案:特定于用户的注册表移动到用户自己的“应用程序数据”文件夹中的user.dat,并且仅在登录(WinNT)时加载。
  • 问题:在大型公司环境中,您需要登录多台计算机,并且必须设置“每个”。
  • 解决方案:区分本地(本地设置)和漫游(应用程序数据)配置文件(WinXP)。
  • 问题:无法xcopy像其他.Net一样部署或移动应用程序。
  • 解决方案:APP.CONFIG XML文件与application-位于同一文件夹中,易于阅读,易于操作,易于移动,并且可以跟踪是否已更改(.Net1)。
  • 问题:仍然需要以类似的方式(即xcopy部署)存储用户特定的数据。
  • 解决方案:用户本地或漫游文件夹中的USER.CONFIG XML文件,并使用强类型(.Net2)。
  • 问题:CONFIG文件区分大小写(对人类而言不直观),需要非常特定的打开/关闭“标签”,无法在运行时设置连接字符串,安装项目无法写入设置(与注册表一样容易),无法轻松确定每个安装的新修订版都炸掉了user.config文件和用户设置。
  • 解决方案:使用ITEM成员在运行时设置连接字符串,在安装程序类中编写代码以在安装过程中更改App.Config,如果找不到用户设置,则使用应用程序设置作为默认设置。

这比已批准的答案要完整得多。谢谢@AndrewD。
rotman

8

如果您在Windows注册表中存储几个窗口位置和最近使用过的项目列表,世界将会终结吗?到目前为止,对我来说还好。

HKEY-CURRENT-USER是一个存储少量用户数据的好地方。这就是它的目的。仅仅因为其他人滥用了它而没有将它用于预期的目的似乎很愚蠢。


而且擅长破坏自己……这是一个加分。用户要做的工作更少...
SnakeDoc

4

您希望在用户的漫游配置文件中可用的设置应该在注册表中,除非您实际上是想手动查找用户的“应用程序数据”文件夹。:-)


4

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


2

如果你正在开发一个新的应用程序,你关心的可移植性,你应该永远不会存储在Windows注册表的数据,因为其他的操作系统没有(窗口)注册表(杜注-这可能是明显的,但被常常被忽视)。

如果您仅针对Win平台进行开发,请尽量避免使用它。配置文件(可能已加密)是一种更好的解决方案。将数据存储到注册表中没有任何好处-(例如,如果使用.NET,隔离存储是更好的解决方案)。


这是部分正确的。Mono已经为注册表实现了Microsoft.win32命名空间-除了它将它存储在xml文件中〜/ .mono / Registry中的文件中,并且可以透明地对其进行处理。现在,如果您可以为任何应用程序打开xml处理功能,无论使用哪种平台……
Robert P 2009年

注意:仅在编写.NET / Mono应用程序时可用。
罗伯特·P

注册表确实带来了好处:在多线程应用程序中可以更轻松地访问数据。更重要的是,它允许您分离特定于计算机的特定于用户的配置数据。您的应用程序在访问HKEY_CURRENT_USER时不必知道谁登录。但是,您对可移植性是正确的。
詹姆斯

2

有点题外话,但是由于我看到有人担心可移植性,所以我使用过的最好的方法是Qt的QSettings类。它抽象化设置的存储(Windows上的注册表,Mac OS上的XML首选项文件和Unix上的Ini文件)。作为班级的客户,我不必花时间去思考注册表或其他任何东西,它就是Just Works(tm)。

http://doc.trolltech.com/4.4/qsettings.html#details


似乎该网址不再起作用。更新参考应该是qt-project.org/doc/qt-5/QSettings.html#details
Eineki 2014年

0

通常,如果您不将设置放入注册表中,则通常将其用于获取当前Windows设置,更改文件关联等。
现在,如果需要检测软件是否已安装,则可以在注册表中进行最少的输入,这是您可以在任何配置中找到的位置。或者在“应用程序数据”中搜索给定名称的文件夹。

如果查看“文档和设置”文件夹,则会看到许多使用Unix点表示法设置文件夹的软件:.p4qt .sqlworkbench .squirrel-sql .SunDownloadManager .xngr .antexplorer .assistant .CodeBlocks .dbvis .gimp-2.4 .jdictionary .jindent .jogl_ext(等)

在“应用程序数据”中,带有编辑器名称或软件名称的各种文件夹。看起来是当前的趋势,至少在便携式应用程序中……
WinMerge使用略有不同的方法,将数据存储在注册表中,但是在配置对话框中提供了“导入和导出”选项。


您看到的Unix点符号可能是因为所有这些示例都是移植的开源项目,而不是因为它是Windows开发的最佳实践。
詹姆斯

确实,我没有说这是“最佳实践”,而是常见实践……:)应用程序数据中的文件夹是最佳实践,尤其是对于大数据,这是因为它们更易于备份。
PhiLho

0

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



0

(稍后讨论)简短答案:组策略。

如果客户的IT部门想要强制执行与Windows或您正在编写或捆绑的组件相关的设置,例如链接速度或自定义错误消息,或要连接的数据库服务器,则通常通过组策略完成,它最终体现为存储在注册表中的设置。这些策略从Windows启动或用户登录时开始执行。

有一些工具可以创建自定义ADMX模板,这些模板可以将组件的设置映射到注册表位置,并为管理员提供一个通用界面来执行他需要执行的策略,同时仅向他们显示对执行此方法有意义的那些设置。


-1

我相信Windows注册表是一个好主意,但是由于应用程序开发人员的大量滥用以及Microsoft不鼓励/要求的标准策略,它变得难以管理。由于您提到的原因,我不喜欢使用它,但是在某些情况下使用它很有意义:

  • 卸载应用程序后留下应用程序的痕迹(例如,记住用户的首选项,以防再次安装该应用程序)
  • 在不同应用程序之间共享配置设置-组件

5
对于您的第一点,我不同意“ [l]在卸载应用程序后留下应用程序的痕迹”。我希望如果我说“从系统中删除自己”,则表明您的应用完全符合要求。我想如果您问用户是否可以保留某些内容,情况可能会有所不同,但是即使那样,我可能还是希望它成为保存的配置文件。尽管有许可等方面的规定,但是如果您要出售计算机并购买新计算机,您是否不希望有一个可以在全新安装中加载的设置文件,而不是与您出售的计算机捆绑在一起的文件?
AgentConundrum

2
许多应用程序都这样做,您应该说这不是一件好事,尤其是在未经用户许可的情况下。但是,通常这是用户期望从应用程序获得的功能(大多数用户不知道注册表是什么)。用户只希望在卸载并重新安装时再次自动神奇地找到其设置。
kgiannakakis

2
我认为我们在这里找到了一个恶意软件作者。如果有人要求您卸载程序,请不要在程序中将废话留在别人的系统上。至少问他们是否想记住设置等。永远不要这样做。如果您存储了许可证密钥而我卖了计算机怎么办?如果您的程序在我的计算机上引起问题,而我尝试卸载以解决该问题怎么办?好吧,您的注册表剩余部分可能会给我带来很多问题。只是不要这样做。只是不要。
SnakeDoc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.