Windows注册表最佳实践

20
Windows注册表应该如何使用?我知道把少量用户偏好存储在其中是可以的,但是把所有用户数据都存储在那里是否被认为是不良实践?我认为这取决于数据集,那么对于少量数据,比如100个左右的键/值对,每个键/值对小于2KB,这样做是否是不良实践?使用平面文件或SQLite数据库是否更好?
8个回答

17

我持有一种反其道而行之的观点。

注册表是放置各种配置数据的良好位置。通常来说,它比大多数配置文件更快,更可靠(在注册表上执行的单个操作是经过事务处理的,因此如果应用程序在写入时崩溃,注册表不会损坏——通常情况下 ini 文件不具备这种特性)。

Marcelo MD 是完全正确的:像操作完成百分比之类的东西存储在注册表中(或任何其他非易失性存储器中)都是一个可怕的想法。另一方面,像最近使用的文件之类的数据存储在其中则完全没有问题——注册表就是为解决此类问题而构建的。

本帖子中其他评论者中讨论 MRU 列表出现故障时会发生什么问题的人提到了一个问题。我想知道将 MRU 列表存储在每个用户存储中的平面文件中是否更好?

我也不确定将您的数据存储在注册表中的“安全影响”是什么。注册表与文件系统一样安全——注册表和文件系统使用相同的 ACL 机制来保护其数据。

如果您确实要将用户数据存储在文件中,至少应该将其放在%APPDATA%\公司名称\应用程序名称中,这样如果两个不同的开发人员创建一个具有相同名称的应用程序(有多少个“媒体管理器”应用程序存在?),您就不会遇到冲突。


12

对于我来说,简单的用户配置项和用户数据最好存储在一个简单的XML配置文件、SQLite数据库或MS SQL Server Compact数据库中。确切的存储介质取决于具体实现情况。

我只在需要很少设置并且用户不需要能够更改/查看的情况下使用注册表。例如,我曾经将加密许可证信息存储在注册表中以避免用户意外删除该数据。


2
你所指的“安全和其他影响”是指哪些方面? - quux
我不认为文件系统的安全问题与注册表的安全问题有任何不同。 - Alex
在Windows 7中访问注册表需要提升权限,但实际上除非您尝试钩取注册表以进行自动启动等操作,否则并不需要。因此,我会避免这样做,因为我喜欢保持我的系统尽可能少的特权。 - Mitchel Sellers

7
使用注册表存储数据主要存在一个问题:它不太用户友好。用户几乎没有机会备份其设置,将其复制到另一台计算机,如果设置损坏了就进行故障排除(或重置),或者通常只是查看其软件正在做什么。
我的经验法则是仅使用注册表与操作系统通信。文件类型关联、卸载程序条目、启动时运行的进程,这些显然必须在注册表中。
但仅供应用程序使用的数据应该放在您的App Data文件夹中的文件中。(无论Microsoft当前希望您使用的3个以上的App Data文件夹中的哪一个)

1
非高级用户不会这样做,但是他们备份%APPDATA%/MyApp中的文件也很困难。注册表易于导出和导入 - 找到您的树(在HKCU/Software/MyApp或其他地方),右键单击并导出。就像压缩目录一样简单。 - gbjbaanb
这个用户体验的观点为我提供了选择最佳实践的子弹。 - Sandburg

6

由于每个用户在Windows中都有专门用于存储应用程序用户数据的目录空间,因此我使用它来存储用户级数据(例如首选项)。

在C#中,可以通过以下方式获取它:

Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData);

通常,我会在那里存储SQLite文件或适用于应用程序的其他文件。

4
如果你的应用程序将要部署在企业中,请记住管理员可以使用组策略工具来调整注册表。例如,如果Firefox使用注册表来处理代理服务器等内容,那么部署就会变得轻而易举,因为管理员可以使用活动目录中的标准工具来设置它。如果你使用其他任何东西,我认为这样的事情很难做到。
因此,不要完全忽略注册表。如果有机会让管理员想要在网络上标准化你配置的某些部分,请将设置放入注册表中。

此外,如果您真的想要使您的应用程序更加企业友好,您可以有意地从注册表的策略部分读取设置,并提供ADM和/或ADMX模板以配合您的应用程序。 - Ryan Bolger

2
我认为微软正在鼓励使用隔离存储而不是Windows注册表。 这篇文章解释了如何在.Net中使用它。
你可以在Windows XP的Documents & Settings\\Local Settings\ App Data\Isolated Storage下找到这些文件。数据保存在.dat文件中。

请注意,独立存储中的文件只能被一个特定程序集访问,因此您不能轻松地在卸载程序中删除用户 IS 中的首选项。在开发过程中手动查找数据文件也很繁琐。所需的是为公司生成一个唯一密钥的方法(例如,CompanyName\ProductName 或 GUID),以便多个 .exes 可以共享数据文件,并且如果需要,开发人员/用户可以轻松地找到它们。因此,IS 已经过时了,%AppData% 万岁。 - Jason Williams

2
我想区分:
一方面,应用程序需要运行的特定于应用程序的配置数据,例如连接的IP地址,哪些文件夹用于什么类型的文件等,以及非平凡的每个用户设置。我将这些放在一个配置文件中,对于简单的东西,使用ini格式,如果更复杂,则使用xml。
另一方面,有微不足道的每个用户设置(最好的例子:窗口位置和布局)。为了避免混乱的配置文件(某些用户将希望自己编辑,因此必须有少量且明确排列的条目),我喜欢将它们放在注册表中(如果在注册表中找不到设置,则在应用程序中设置保守默认值)。
我主要像istmatt所说的那样:我将配置文件存储在%APPDATA%文件夹中。通常在%APPDATA%\ApplicationName中,我不喜欢.NET默认的APPDATA%\CompanyName\ApplicationName\Version,对于大多数中小型应用程序来说,这种详细程度和复杂性是适得其反的。
我不同意Marcelo MD的例子,即不要在注册表中存储最近使用的文件。我认为这正是可以在那里存储的易失性用户特定信息的例子。(但他的反面例子非常好!)

1

对我来说,更容易想到不应该放置哪些内容。 例如:动态数据,比如编辑器的“最近打开的文件”和每个项目的选项。当您的应用程序与注册表失去同步(文件删除、系统崩溃等)并检索不再有效的信息时,可能会使用户死锁,这真的很烦人。

在早期的工作中,我看到一个人将数据传输完成百分比存储在那里,每10k左右写入新值,并让GUI每秒检索此值,以便可以显示在标题栏上。


天啊!我以为我以前的一些用法很糟糕!(不,我真的不想分享!) - Michael Itzoe
哦,别害羞!我们不会告诉任何人,真的! - Treb
我不明白。为什么这个人会在他的应用程序的一部分中写入注册表,然后轮询并读取注册表中的值以进行显示?这似乎很愚蠢,与持久性机制无关。 - MusiGenesis
那个系统被用来与许多不同的外围设备通信,协议函数被分组在DLL中。问题是该系统没有设计用于发送大块数据,并且没有任何信息反馈的规定,所以无论如何都会成为一个黑客。我?我可能会使用纯文本文件。 - Marcelo MD

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