Im letzten Kapitel haben wir die Registry geöffnet und befinden uns nun im Hauptpfad der installierten Software. Da wir nicht wissen können, welche Software der Anwender installiert hat, brauchen wir eine Möglichkeit, die vorhandenen Schlüssel der Reihe nach auszulesen.
Diese Möglichkeit heißt
Zur Ausführung benötigen wir zunächst natürlich ein Zeichenarray (pchar). Es bleibt dabei Ihnen überlassen, wie Sie vorgehen. Sie können das Array so deklarieren:
var
pBuf : array[0..MAX_PATH]of char;
Oder Sie ermitteln die Größe des Puffers zur Laufzeit und deklarieren die Variable dann so:
var pBuf : pchar;
Es funktioniert deshalb beides, weil (laut PSDK) die Länge für einen Schlüsselnamen max. 255 Zeichen beträgt. Und wenn Sie ein statisches Array verwenden wollen (s. erste Deklaration von "pBuf"), umfasst dieses durch MAX_PATH ja sowieso 260 Zeichen.
Aufpassen sollten Sie, wenn Sie mit der Unicode-Version, "RegEnumKeyExW", arbeiten wollen. Sie liefert einen Zeiger auf ein WideChar-Array, bzw. sie erwartet als Puffer ein solches Array; und hier belegt jedes Zeichen im Array zwei Bytes. Sie sollten also die doppelte Puffergröße verwenden.
Neben dem Zeichenarray benötigen wir eine dword-Variable, die die Länge des Puffers angibt. Diese Länge muss vor jedem neuen Aufruf von "RegEnumKeyEx" auf den Maximalwert des Puffers zurückgesetzt werden! Warum?
Die Variable wird an die Funktion übergeben und von dieser auf die tatsächliche Länge des ermittelten Schlüsselnamens gesetzt. Nehmen wir als Beispiel an, der ermittelte Name lautet "IE40". Dann wird der Wert der dword-Variablen auf 4 gesetzt, da ja nur 4 Zeichen kopiert wurden.
Würden wir die Funktion nun ein zweites Mal aufrufen und dabei die Länge nicht auf die Puffergröße zurücksetzen, bekäme "RegEnumKeyEx" die Anweisung, den nächsten Schlüsselnamen in einen 4 Bytes großen Puffer zu kopieren. Wenn der nächste Name allerdings mehr Zeichen aufweist, wäre der Fehler ERROR_MORE_DATA die Folge.
Und zu guter Letzt benötigen wir eine Zählervariable, die wir auf Null setzen und solange um Eins erhöhen, bis die Funktion ERROR_NO_MORE_ITEMS als Ergebnis zurückliefert.
Schauen wir uns zunächst das einfachere Beispiel an, bei dem wir ein "array[0..MAX_PATH]of char" als Puffer verwenden:
i := 0;
while(true) do begin ZeroMemory(@pBuf,sizeof(pBuf)); dwLen := sizeof(pBuf);
Wie bereits angesprochen: wir setzen die Zählervariable "i" auf Null, da sie als Ausgangspunkt unserer Enumeration dient. Dann treten wir in eine Endlosschleife ein, leeren den Puffer und setzen die dword-Variable ("dwLen") auf die Puffergröße.
Jetzt rufen wir die Funktion auf und geben zuerst das Handle unseres geöffneten Schlüssels an:
retcode := RegEnumKeyEx(rgHandle,
Es folgt unsere Zählervariable
i,
unser Puffer
pBuf,
und dessen Größe
dwLen,
Die vier weiteren Parameter sind für uns nicht von Bedeutung und werden von uns daher auch ignoriert:
nil, nil, nil, nil);
Wenn es keine weiteren Schlüssel gibt, dann sollten wir die Schleife natürlich verlassen:
if(retcode = ERROR_NO_MORE_ITEMS) then break;
Wenn die Funktion erfolgreich ausgeführt werden konnte, dann befindet sich nun der Name des ersten bzw. nächsten Unterschlüssels im Zeichenpuffer, und wir können ihn in unsere Liste eintragen oder anderweitig be- oder verarbeiten
if(retcode = ERROR_SUCCESS) then
begin
{ ... }
end;
Und damit wir kein "hängendes" Programm basteln, das sich auf Nimmerwiedersehen verabschiedet, sollten wir unbedingt unsere Zählervariable erhöhen, damit wir irgendwann den Fehler ERROR_NO_MORE_ITEMS provozieren und die Schleife verlassen können.
inc(i); end;
Sie können auch auf Nummer Sicher gehen und nur auf ERROR_SUCCESS prüfen; sollte diese Prüfung negativ verlaufen, verlassen Sie die Schleife mit "break". Auf die Weise ist sichergestellt, dass andere evtl. auftretende und unvorhergesehene Fehler Ihr Programm nicht abschießen.