tags:

views:

696

answers:

3

I am looking for a clean way to check if a registry key exists. I had assumed that RegOpenKey would fail if I tried to open a key that didn't exist, but it doesn't.

I could use string processing to find and open the parent key of the one I'm looking for, and then enumerating the subkeys of that key to find out if the one I'm interested in exists, but that feels both like a performance hog and like a weird way to have to implement such a simple function.

I'd guess that you could use RegQueryInfoKey for this somehow, but MSDN doesn't give too many details on how, in case it's possible.

Update: I need the solution in straight win32 api, not in managed code, .NET or any other library.

The docs in MSDN seem to indicate that you should be able to open a key for read permission and get an error if it doesn't exist, like this:

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

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

However, I get ERROR_SUCCESS when I try this.

Update 2: My exact code is this:

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

... but result comes out as ERROR_SUCCESS, even though I've put in a key that does not exist.

Update 3: It looks like you guys are right. This fails on one specific test example (mysteriously). If I try it on any other key, it returns the correct result. Doublechecking it with the registry editor still does not show the key. Dunno what to make of that at all.

+6  A: 

First of all don't worry about performance for stuff like this. Unless you are querying it 100x per sec, it will be more than fast enough. Premature optimization will cause you all kinds of headaches.

RegOpenKeyEx will return ERROR_SUCCESS if it finds the key. Just check against this constant and you are good to go.

Byron Whitlock
Well, this is not so much a case of premature optimization as of not wanting to add that kind of complexity to the code.
slicedlime
+3  A: 

RegOpenKey does return an error if the key does not exist. How are you using it? The expected return value is ERROR_FILE_NOT_FOUND.

From your code:

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

I would look at the value of key and subPath and make sure they are what you expect, and that the key does not actually exist. What is the value of subKey afterwards? It is obviously opening something - try enumerating it to see what the keys and values under it are.

There is no issue with RegOpenKey not returning an error if the key does not exist - I would not try to assume there is some kind of weird OS bug in something as commonly used as the registry.

Maybe you have a registry key that is not visible to you, the user that is running the registry editor, but not to your code? A permissions problem perhaps? Is your code running as an elevated user in windows Vista or server 2008? Did you try running the registry editor as administrator?

1800 INFORMATION
You can also get ERROR_PATH_NOT_FOUND
Billy ONeal
A: 

Note that beside the "core" Registry functions that start with "Reg" there are also helper functions starting with "SHReg". These are intended for use by the Shell i.e. Explorer but are documented and can be used in normal applications too. They're typically thin wrappers that make some common tasks easier. They're part of the "Shell LightWeight API" (shlwapi.dll)

MSalters