2009-08-27 131 views
7

我正在寻找一种干净的方式来检查注册表项是否存在。我曾假设如果我试图打开一个不存在的密钥,RegOpenKey会失败,但它不会。检查是否存在注册表项

我可以使用字符串处理来查找并打开我正在查找的父键,然后枚举该键的子键以查明我感兴趣的键是否存在,但这两者都感觉到就像性能猪一样,并且像一种奇怪的方式来实现这样一个简单的功能。

我想你可以使用RegQueryInfoKey为此,但MSDN并没有提供太多的细节,以防万一它是可能的。

更新:我需要直接win32 API的解决方案,而不是托管代码,.NET或任何其他库。

MSDN中的文档似乎表明,你应该能够打开读取权限的关键,并得到一个错误,如果它不存在,就像这样:

lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); 

if (lResult != ERROR_SUCCESS) 
{ 
    if (lResult == ERROR_FILE_NOT_FOUND) { 

不过,我得到ERROR_SUCCESS时我试试这个。

更新2:我确切的代码是这样的:

HKEY subKey = nullptr; 
LONG result = RegOpenKeyEx(key, subPath.c_str(), 0, KEY_READ, &subKey); 
if (result != ERROR_SUCCESS) { 

...但结果出来为ERROR_SUCCESS,即使我已经把不存在的关键。

更新3:看起来你们是对的。这在一个特定的测试例子上(神秘地)失败了。如果我在任何其他键上尝试它,它会返回正确的结果。使用注册表编辑器对其进行双重检查仍然不会显示密钥。不知道该怎么做。

+4

你正在检查的密钥的路径是什么?是否有可能遇到重定向的魔法路径之一(如Wow6432Node)?我有一个模糊的回忆,以前看到这个问题。我想你可以打开一个不存在的密钥。实际尝试设置或查询该密钥中的值时,您会失败。 – 2009-08-27 21:37:01

+1

它也可以在[注册表VirtualStore](http://msdn.microsoft.com/en-us/library/windows/desktop/aa965884%28v=vs.85%29.aspx)。 – ghord 2013-05-31 11:48:17

回答

7

首先,不要担心像这样的东西的表现。除非你每秒查询它100次,否则它会更快。不成熟的优化会导致各种头痛。

如果RegOpenKeyEx找到密钥,它将返回ERROR_SUCCESS。只要检查这个常数,你就很好。

+1

好吧,这不是一个过早优化的例子,因为不想为代码增加这种复杂性。 – slicedlime 2009-08-27 20:58:33

4

RegOpenKey如果密钥不存在,会返回错误。你怎么使用它?预期回报值为ERROR_FILE_NOT_FOUND

从代码:

HKEY subKey = nullptr; 
LONG result = RegOpenKeyEx(key, subPath.c_str(), 0, KEY_READ, &subKey); 
if (result != ERROR_SUCCESS) { 

我会看的keysubPath的价值,并确保他们是你所期望的,那关键的实际上不存在。之后subKey的价值是多少?这显然是开放的东西 - 尝试枚举它,看看它下面的键和值是什么。

如果密钥不存在,那么RegOpenKey不会返回错误 - 我不会试图假设在注册表中常用的东西中存在某种奇怪的操作系统错误。

也许你有一个注册表项对于你来说是不可见的,它是运行注册表编辑器但不是你的代码的用户?权限问题可能是?您的代码在Windows Vista或Server 2008中作为高级用户运行吗?您是否尝试以管理员身份运行注册表编辑器?

+0

你也可以得到ERROR_PATH_NOT_FOUND – 2010-03-17 19:14:21

0

请注意,除了以“Reg”开头的“核心”注册表函数外,还有以“SHReg”开头的辅助函数。这些文件适用于use by the Shell即Explorer,但有文档记录,并且也可用于普通应用程序。它们通常是很薄的包装器,可以使一些常见任务更容易。它们是“Shell LightWeight API”的一部分(shlwapi.dll)