Link to home
Start Free TrialLog in
Avatar of tayto
tayto

asked on

Search Registry

Can anyone help me with this...

I am making a program that will store some data in the registry in the following layout:

HKEY.......\program name

Inside program name i have more keys so the layout looks like this:

HKEY......\program name\data1
HKEY......\program name\data1\a\my value keys
HKEY......\program name\data1\145\my value keys
HKEY......\program name\data1\abc\my value keys

and so on.......

HKEY......\program name\data2\my value keys
HKEY......\program name\data2\478\my value keys
HKEY......\program name\data2\tfg\my value keys
HKEY......\program name\data2\xyz\my value keys

and so on.......

HKEY......\program name\data3\my value keys
HKEY......\program name\data3\tyu\my value keys
HKEY......\program name\data3\3cd\my value keys
HKEY......\program name\data3\zasdrftg\my value keys

and so on.......

I am NOT using the Registry unit for accessing the registry to keep the file size down - the file is already huge enough.

What i want to be able to do is search  in HKEY......\program name\ and check if a certain branch exists for example \tyu

I am not interested in getting the value of any of the keys inside just interested in checking that the branch exists already.


Anyone know how i can do this?
Avatar of Ferruccio Accalai
Ferruccio Accalai
Flag of Italy image

Using API RegOpenKey...if Key does exists the result is ERROR_SUCCESS and if not the result is a non zero value

 RegOpenKey does not create the specified key if the key does not exist in the database!

from delphi SDK Help:

The RegOpenKey function opens the specified key. This function is provided for compatibility with Windows version 3.1. Win32-based applications should use the RegOpenKeyEx function.

LONG RegOpenKey(

    HKEY hKey,      // handle of open key
    LPCTSTR lpSubKey,      // address of name of subkey to open
    PHKEY phkResult       // address of handle of open key
   );      
 

Parameters

hKey

Identifies a currently open key or any of the following predefined reserved handle values:

HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
The key opened by the RegOpenKey function is a subkey of the key identified by hKey.

lpSubKey

Points to a null-terminated string containing the name of the key to open. This key must be a subkey of the key identified by the hKey parameter. If this parameter is NULL or a pointer to an empty string, the function returns the same handle that was passed in.

phkResult

Points to a variable that receives the handle of the opened key.

 

Return Values

If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is a nonzero error code defined in WINERROR.H. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

Remarks

The RegOpenKey function uses the default security access mask to open a key. If opening the key requires a different mask, the function fails, returning ERROR_ACCESS_DENIED. An application should use the RegOpenKeyEx function to specify an access mask in this situation.
Unlike the RegCreateKey function, RegOpenKey does not create the specified key if the key does not exist in the database.

Avatar of tayto
tayto

ASKER

Thanks Ferruccio68 but i am looking to enumerate through the different sections to see if a a branch exists already
Hi,

Use RegEnumKeyEx API. But I think that using Registry.pas would be easier. Otherwise you'll have to rewrite it yourself and your app's size will be almost the same.

Regards, Geo
You'll need RegQueryInfoKey API also.
Avatar of tayto

ASKER

Yes, but how can i do it (without using the TRegistry unit of course).

I'm a bit lost in how to code it all
ASKER CERTIFIED SOLUTION
Avatar of geobul
geobul

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tayto

ASKER

thanks geo - i played around with the code you gave and got it to do what i wanted
You don't want to enumerate subkeys but to find if a certain key exists somewhere in a tree. So, it would be:

-----
unit Unit2;

interface

uses Windows, Classes, SysUtils;

function FindRegKey(Root: HKEY; SubKey: string; What: string): boolean;

implementation

type
  TRegKeyInfo = record
    NumSubKeys: Integer;
    MaxSubKeyLen: Integer;
    NumValues: Integer;
    MaxValueLen: Integer;
    MaxDataLen: Integer;
    FileTime: TFileTime;
  end;

function FindRegKey(Root: HKEY; SubKey: string; What: string): boolean;
var
  Info: TRegKeyInfo;
  i: integer;
  sl: TStringList;
  Status: Integer;
  Key: HKEY;
  Len: DWORD;
  S: string;
begin
  result := false;
  sl := TStringList.Create;
  try
    // open current key
    Status := RegOpenKeyEx(Root, PChar(SubKey), 0, KEY_READ or KEY_ENUMERATE_SUB_KEYS, Key);
    if Status = ERROR_SUCCESS then
    try
      // get key info
      FillChar(Info, SizeOf(TRegKeyInfo), 0);
      Status := RegQueryInfoKey(Key, nil, nil, nil, @Info.NumSubKeys,
                @Info.MaxSubKeyLen, nil, @Info.NumValues, @Info.MaxValueLen,
                @Info.MaxDataLen, nil, @Info.FileTime);
      if Status  = ERROR_SUCCESS then begin
        // enum subkeys
        SetString(S, nil, Info.MaxSubKeyLen + 1);
        for i := 0 to Info.NumSubKeys - 1 do begin
          Len := Info.MaxSubKeyLen + 1;
          RegEnumKeyEx(Key, i, PChar(S), Len, nil, nil, nil, nil);
          sl.Add(PChar(S));
        end;
      end;
    finally
      RegCloseKey(Key);
    end;
    // search current key
    if sl.IndexOf(what) > -1 then begin
      result := true;
    end else begin
      // search subkeys
      if sl.Count > 0 then begin
        for i := 0 to sl.Count - 1 do begin
          result := FindRegKey(Root, SubKey + '\' + sl[i], what);
          if result then break;
        end;
      end;
    end;
  finally
    sl.Free;
  end;
end;

end.
-----
// and usage:
if FindRegKey(HKEY_CURRENT_USER, 'program name', 'tyu') then ShowMessage('Yes')
  else ShowMessage('No');
Thanks tayto :-)