检查是否存在注册表项

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

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

我猜你可以用某种方式使用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) { 

…但resultERROR_SUCCESS ,即使我正在尝试打开一个不存在的密钥。

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

首先不要担心这样的东西的性能。 除非你每秒100x查询它,否则它将足够快。 过早优化会引起各种令人头疼的问题。

如果找到密钥,RegOpenKeyEx将返回ERROR_SUCCESS。 只要检查这个常数,你就可以了。

如果密钥不存在, 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中作为提升用户运行? 您是否尝试以管理员身份运行注册表编辑器?

请注意,除了以“Reg”开头的“核心”注册表函数旁边还有以“SHReg”开头的辅助函数。 这些仅供Shell使用,即Explorer,但有记录,也可用于普通应用程序。 它们通常是薄包装,使一些常见任务更容易。 他们是“Shell LightWeight API”(shlwapi.dll)的一部分