Registry (fast) ohne WinAPI



  • Hallo, da ja öfters mal Registy-Fragen kommen und so einige ihre Probleme mit den WinAPI-Funktionen haben (oder so faul sind wie ich [img]images/smiles/icon_biggrin.gif[/img] ), stelle ich hier die MFC-Version vor.

    Die Klasse der MFC heißt CRegKey und sie muss durch #include <atlbase.h> eingebunden werden.

    Schlüssel ("Ordner") werden mit der Methode Open() geöffnet.

    key.Open( HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired = KEY_ALL_ACCESS);
    1.Parameter: HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER usw.
    2.Parameter: Pfad des Unterschlüssels (z.B. "SOFTWARE\MICROSOFT")
    3.Parameter: Zugriffsart; KEY_READ, KEY_WRITE, KEY_QUERY_VALUE ( siehe MSDN)

    /*****************************************************************/

    Am häufigsten benötigt man das Lesen und Schreiben von Werten
    (Zeichenfolgen, DWORD-Werte, Binärwerte)

    Schreiben von Werten:

    Dazu verwendet man die Funktion CRegKey::SetValue().

    Die erste Version setzt einen String vom Typ REG_SZ, die zweite einen DWORD-Wert vom Typ REG_DWORD.
    Binärwerte (REG_BINARY) muss man mit WinAPI machen (sind in der Praxis aber selten).

    Beispiele (Existenz des Schlüssel vorausgesetzt):

    Erzeugen der Zeichenfolge "Hallo Welt" im Schlüssel HKEY_CURRENT_USER\SOFTWARE\TEST mit Eintragsnamen "StringEintrag".

    CRegKey key;
    key.Open( HKEY_CURRENT_USER, "SOFTWARE\\TEST", KEY_WRITE);
    key.SetValue( "Hallo Welt", "StringEintrag");
    key.Close();
    

    Erzeugen der DWORD-Zahl 4711 im Schlüssel HKEY_CURRENT_USER\SOFTWARE\TEST mit Eintragsnamen "DWORDEintrag".

    CRegKey key;
    key.Open( HKEY_CURRENT_USER, "SOFTWARE\\TEST", KEY_WRITE);
    key.SetValue( 4711, "DWORDEintrag");
    key.Close();
    

    SetValue kann in der ersten Version (mit Strings) auch mit nur einem Parameter aufgerufen werden. In dem Fall wird der Wert des Eintrags "(Standard)" gesetzt.

    Lesen von Werten:

    Lesen von Zeichenketten:

    CRegKey key;
    char buffer[256];
    DWORD dwCount = sizeof( buffer);
    key.Open( HKEY_CURRENT_USER, "SOFTWARE\\TEST", KEY_READ);
    key.QueryValue( buffer, "StringEintrag", &dwCount);
    key.Close();
    

    Leider kann man hier nicht mit CStrings arbeiten und muss auf die unschönen C-Strings zurückgreifen.

    Lesen von DWORD-Zahlen:

    CRegKey key;
    DWORD dwValue;
    key.Open( HKEY_CURRENT_USER, "SOFTWARE\\TEST", KEY_READ);
    key.QueryValue( dwValue, "DWORDEintrag");
    key.Close();
    

    /*******************************************************************/

    Erzeugen von neuen Schlüsseln:

    Neue Schlüssel werden mit der Methode CRegKey::Create() erzeugt. Die Parameter sind ähnlich der WinAPI-Funktion RegCreateKeyEx() und deswegen wird hier auf die Erläuterung verzichtet.
    Falls der Schlüssel bei Create schon existiert, ist er anschließend geöffnet. (Als hätte man ihn mit Open geöffnet.)

    Löschen von Werten/Schlüsseln

    Werte sind mit CRegKey :: DeleteValue() zu löschen.
    Einziger Parameter ist der Name des Eintrags.

    Schlüssel ohne Unterschlüssel werden mit CRegKey :: DeleteSubKey() gelöscht.
    Anzugeben ist als Parameter der Name des Unterschlüssels.

    Falls zu löschende Schlüssel noch Unterschlüssel besitzen, musste man unter WinAPI zu Fuss die Unterschlüssel enummerieren und löschen.
    CRegKey bietet dafür die Methode RecurseDeleteKey() an, die wie der Name schon sagt, den Schlüssel samt aller Unterschlüssel löscht; unabhängig von der Verschachtelungstiefe.

    Was CRegKey nicht bietet, ist z.B. das Enummerieren von Unterschlüsseln.

    Zum Schluss noch der Link zur WinAPI-FAQ.

    @deus: Da du ja keinen Beitrag für die FAQ schreiben willst [img]images/smiles/icon_smile.gif[/img] , mach ich das mal. Ich hoffe, dass meine Ausführungen ein bisschen verständlich sind.
    Falls Fehler im Text sind, bitte korrigieren.

    Edit von estartu_de: Link zur Win-Api FAQ korrigiert.
    [ Dieser Beitrag wurde am 30.01.2002 um 09:19 Uhr von thomas80d editiert. ]



  • Dieses Posting sollte in der Tat wirklich in`s FAQ. Es ist sehr gut und verständlich geschrieben. Es wäre jedoch nicht schlecht, wenn Du noch die Parameter der key.QueryValue-Funktion erläutern könntest.

    Auch würde mich noch folgende Sache interessieren: Ich will im Grunde nur Testen, ob ein Schlüssel in der Registry vorhanden ist. Wenn ja, soll z.B. der Wert 1, wenn nicht, der Wert -1 zurück geliefert werden.
    Gibt es eine Funktion, die so etwas in der Art macht?



  • Eigentlich dachte ich, dass die QueryValue-Funktion für sich spricht. Aber dann eben nochmal kurz erklärt:

    CRegKey key;
    char buffer[256];
    DWORD dwCount = sizeof( buffer);
    DWORD dwValue;
    
    key.Open( HKEY_CURRENT_USER, "SOFTWARE\\TEST", KEY_READ);
    
    key.QueryValue( buffer, "StringEintrag", &dwCount);
    key.QueryValue( dwValue, "DWORDEintrag");
    
    key.Close();
    

    In buffer wird der String gespeichert und dwCount enthält nach dem Auslesen die Anzahl der geleseen Zeichen.

    Beim Lesen von DWORD-Werten stehen nach dem Lesevorgang die Zahl in der Variable dwValue.

    Zum Thema Vorhandensein von Schlüsseln bzw. allgemeine Fehlerbehandlung bei Registry-Operationen könnte man schon fast einen neuen Thread aufmachen. Hier jetzt alle möglichen Fehler aufzuzählen, wäre ein bisschen viel.

    Um zu testen, ob ein Key existiert, öffnet man ihn und fängt den Fehlercode ab, den die Methode Open liefert.

    CRegKey key;
    if( key.Open( HKEY_CURRENT_USER, "KeyNotExits") == ERROR_FILE_NOT_FOUND)
        MessageBox( "Schlüssel existiert nicht");
    key.Close();
    


  • Bin grad erst heimgekommen.

    @thomas80d
    sieht super aus! Vielen Dank images/smiles/icon_smile.gif
    Klar kommt das in die FAQ!



  • Danke für diesen super Beitrag.
    Hat mir viel geholfen images/smiles/icon_smile.gif



  • Ich hätte da noch eine Frage.

    Du hast ja geschrieben wie man überprüfen kann, ob ein Key existiert.

    Wie kann man aber nun überprüfen, ob ein Wert existiert oder nicht? images/smiles/icon_sad.gif



  • Original erstellt von CrazyOwl:
    **

    Wie kann man aber nun überprüfen, ob ein Wert existiert oder nicht? images/smiles/icon_sad.gif**

    QueryValue() liefert bei Nichtvorhandensein auch den Fehlercode ERROR_FILE_NOT_FOUND.

    Wenn alles geklappt hat, wird ERROR_SUCCESS zurückgegeben.


Anmelden zum Antworten