Registry Einträge in einer Datei abspeichern



  • schade, daß du meine Antworten scheinbar nicht alle richtig oder genau gelesen hast 😞

    dieselbe Frage hast du nämlich bereits weiter oben gestellt, und ich rezitiere meine Antwort:

    Probe-Nutzer schrieb:

    DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion",0, KEY_ALL_ACCESS, &hkey);

    erst damit bekommt man ein Handle (in hkey) auf einen Sub-Key der den vordefinierten Registry-Key-Handles entsprechenden Schlüssel (und dort gibst du einfach den dich interessierenden Pfad zum Sub-Key an). Dieser dadurch erhaltene hkey tritt anstelle des in dieser Zeile:

    hKey=HKEY_LOCAL_MACHINE;

    verwendeten hkey.

    man kann die SaveReg-Funktion jetzt noch intelligenter machen, in dem man ihr als Argument den zu speichernden hkey übergibt:

    DWORD SaveReg(HKEY hKey) 
    { 
       TOKEN_PRIVILEGES tp; 
       HANDLE hToken; 
       LUID luid; 
       LONG rc;     // contains error value returned by Regxxx() 
    
       DWORD dwSubKeyIndex=0;   // index into key 
       char szSubKey[_MAX_FNAME]; // this should be dynamic. 
                                // _MAX_FNAME is good because this 
                                // is what we happen to save the 
                                // subkey as 
       DWORD dwSubKeyLength=_MAX_FNAME; // length of SubKey buffer 
    
        if(!OpenProcessToken(GetCurrentProcess(), 
                            TOKEN_ADJUST_PRIVILEGES, 
                            &hToken )) 
        { 
            AfxMessageBox("OpenProcessToken"); 
            return GetLastError(); 
        } 
    if(!LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &luid)) 
    
        { 
            AfxMessageBox("LookupPrivilegeValue"); 
            return GetLastError(); 
        } 
    
        tp.PrivilegeCount           = 1; 
        tp.Privileges[0].Luid       = luid; 
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    
        AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 
                                    NULL, NULL ); 
    
        if (GetLastError() != ERROR_SUCCESS) 
        { 
            AfxMessageBox("AdjustTokenPrivileges"); 
            return GetLastError(); 
        } 
    
        while((rc=RegEnumKeyEx( 
                            hKey, 
                            dwSubKeyIndex, 
                            szSubKey, 
                            &dwSubKeyLength, 
                            NULL, 
                            NULL, 
                            NULL, 
                            NULL) 
                            ) != ERROR_NO_MORE_ITEMS) { // are we done? 
    
        if(rc == ERROR_SUCCESS) 
       { 
            LONG lRetVal; // return value from SaveRegistrySubKey 
    
            // save registry subkey szSubKey to filename szSubKey 
            if( (lRetVal=SaveRegistrySubKey(hKey, szSubKey, szSubKey) 
                ) != ERROR_SUCCESS) 
            { 
                AfxMessageBox("SaveRegistrySubKey"); 
                return (DWORD) lRetVal; 
            } 
    
            // increment index into the key 
           dwSubKeyIndex++; 
    
           // reset buffer size 
            dwSubKeyLength=_MAX_FNAME; 
    
            // Continue the festivities 
            continue; 
        } 
        else 
       { 
           // 
           // note: we need to watch for ERROR_MORE_DATA 
           // this indicates we need a bigger szSubKey buffer 
           // 
            AfxMessageBox("RegEnumKeyEx"); 
            return (DWORD) rc; 
       } 
    
        } // RegEnumKeyEx 
    
        // Revoke all privileges this process holds (including backup) 
        AdjustTokenPrivileges( hToken, TRUE, NULL, 0, NULL, NULL); 
    
        // close handle to process token 
        CloseHandle(hToken); 
    
        return 0; 
    
    }
    

    dann muß nur der oben angegebene RegOpenKeyEx-Aufruf vor dem Aufruf von SaveReg geschehen, und mit dem hkey, den RegOpenKeyEx zurückgibt, wird SaveReg aufgerufen, ungefähr so:

    void CMFCDlgTestDlg::OnButtonExport()
    {
        // andere Variablen
        HKEY hkey;
        DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion",0, KEY_ALL_ACCESS, &hkey);
    
        SaveReg(hkey);
    
        RegCloseKey(hKey);
    
        // anderer Code
    
    }
    

    und für den Pfad "Software\\Microsoft\\Windows NT\\CurrentVersion" sowie HKEY_LOCAL_MACHINE kann man auch andere angeben

    MfG



  • Sorry,

    das ich da wohl nicht richtig einen Beitrag von Dir gelesen habe. So wie Du es mir nun geschrieben hast funktioniert das schon mal sehr gut, nur noch eine Frage (erstmal):

    Er speichert ja dann zum Beispiel jeden Unterschlüssel von CurrentVersion in einer eigenen Datei, so dass nach meinem Verständnis alles was in z.B. Drivers drin steht, gesichert wird. Wie kann ich das nun machen, das er daraus einen Dateityp mit Namen *.reg macht?

    Danke für Deine Unterstützung!

    PS: Wenn man nun Keys zurücksichern möchte, muss man dann einen ähnlichen Code programmieren, wie Du es für das Saven gemacht hast oder geht dies einfacher?



  • MarKir schrieb:

    Er speichert ja dann zum Beispiel jeden Unterschlüssel von CurrentVersion in einer eigenen Datei, so dass nach meinem Verständnis alles was in z.B. Drivers drin steht, gesichert wird. Wie kann ich das nun machen, das er daraus einen Dateityp mit Namen *.reg macht?

    also das war und ist auch nur das Grundgerüst für das, was du vielleicht eigentlich haben willst. Das Ändern des Dateinamens sollte doch nicht so das Problem sein. Und wenn man nur einen Schlüssel speichern will, dann kann man das auch vereinfachen (man braucht dann RegEnumKeyEx nicht), denn RegSaveKey kann ja einen Schlüssel mitsamt seinen Unterschlüsseln speichern (nur im Beispiel war es nötig, da man von der Root speichern wollte).

    MarKir schrieb:

    PS: Wenn man nun Keys zurücksichern möchte, muss man dann einen ähnlichen Code programmieren, wie Du es für das Saven gemacht hast oder geht dies einfacher?

    es wird dir wohl trotzdem nicht einfacher erscheinen, aber es ist im Grunde ein ähnlicher Code, und die Funktionen findest du in der MSDN (z.B. RegLoadKey)

    MfG



  • Hallo Probenutzer,

    danke erst mal für Deine Antwort.

    Zum Thema umbennen: Ich würde jetzt hingehen und alle Dateien, die sich in einem bestimmten Verzeichnis befinden mit Hilfe eines Rename Codes ( den ich schon habe ) umbenennen.

    Wenn ich nur den einen Key benötige, z.B. die Windows Version, dann könnte ich doch den Code von "Savereg" und "SaveRegistrySubkeys" nochmal programmieren, nur mit anderen Bezeichnern, z.B. "Savereg2" und "SaveRegistrySubkeys2" und dann lasse ich in dem Code den Eintrag "RegEnumKeyEx" weg.

    Das mit dem zurückspielen der Daten werde ich mir dann in der MSDN mal anschauen!



  • Hallo Probe-Nutzer,

    ich muss nochmal was erfragen. Und zwar habe ich jetzt einmal eine Datei extensions.txt und eine Datei extensions.reg hinterlegt, die Du Dir mal anschauen könntest. Die extensions.txt Datei ist mit dem Projekt exportiert und dort stehen leider nur Hyroglyphen drin und die Datei extensions.reg ist mit dem Regeditor exportiert und dort ist da ganze klar lesbar. Was muss ich machen, das meine exportierten Dateien auch so aussehen?

    Danke für Dein Feedback!

    Extensions.txt

    Extensions.reg



  • da hast du etwas falsch verstanden, oder es war dir nicht klar. Das Format, das RegSaveKey speichert (es ist ein Binär-Format), hat nichts mit dem lesbaren .reg-Format zu tun, das man mit regedit exportieren kann. RegSaveKey ist nur dazu gedacht, daß man mit RegLoadKey, RegRestoreKey usw... die Registry wiederherstellen kann, aber nicht, um irgendetwas lesbares zu erzeugen. Wenn du doch das .reg-Format benötigst, dann ist wohl die einfachste Methode, regedit selbst dafür aufzurufen, mit dem Schalter /e. Das ganze ist natürlich viel einfacher, als mit RegSaveKey usw. zu arbeiten, aber das war aus deiner Frage ganz am Anfang nicht zu erkennen, daß du das .reg-Format haben willst. Ein Beispiel dafür gibt es hier:

    http://www.codeguru.com/Cpp/W-P/system/registry/comments.php/c5671/?thread=62188

    MfG



  • Hallo,

    aber *.reg Dateien kann man doch auch wieder in die Registry zurückschreiben, habe ich zumindest schon mal gemacht und das hat funktioniert.
    Es soll natürlich, so wie Du es gesehen hast zur Datensicherung und Wiederherstellung dienen und da ist ja dann Deine Methode die bessere oder täusche ich mich da?

    Noch was:
    Habe gerade nochmal die Funktion aufgerufen und nun bringt er mir immer die Msgbox RegEnumKeyEx und exportiert leider nichts mehr? Was soll ich da machen?

    PS:
    Wenn ich nur den einen Key benötige, z.B. die Windows Version, dann könnte ich doch den Code von "Savereg" und "SaveRegistrySubkeys" nochmal programmieren, nur mit anderen Bezeichnern, z.B. "Savereg2" und "SaveRegistrySubkeys2" und dann lasse ich in dem Code den Eintrag "RegEnumKeyEx" weg, oder?



  • ich habe ja nicht gesagt, daß man .reg-Dateien nicht wieder in die Registry importieren kann (kann ja regedit auch), aber wenn du das schon gemacht hast, ist es ja gut (ist nämlich gar nicht so einfach, wenn du nicht gerade regedit dazu verwendest, denn man müßte die Datei parsen, und alle Informationen extrahieren)

    zum Fehler kann man so nichts sagen. Du kannst den Debugger einsetzen, um den Wert von rc im Fehlerfall festzustellen, dann kann man näheres sagen.

    Wenn du nur einen Schlüssel exportieren willst, kann man, wie schon gesagt, das Enumerieren weglassen, und du kannst natürlich erst einmal zum Test eine neue Funktion mit anderem Namen erstellen, die nur das wichtigste ausführt.

    MfG



  • Hallo Probenutzer,

    ich muss mich, jetzt, wo ich das ein paar Tage sacken lassen habe, damit beschäftigt, wie ich folgendes lösen kann:

    Es gibt mehrere Checkboxen und hinter jeder Checkbox ist ein RegistryKey, der durch den bisherigen Code gesichert werden kann.
    Jetzt würde ich das gerne so lösen, das wenn die erste Checkbox aktviert ist, die Registry Schlüssel im neuanzulegenden Ordner1 abgelegt werden, die Registry Keys der 2. Checkbox in Ordner2 abgelegt werden usw.

    Wie ich einen Ordner neu anlegen kann ist mir geläufig, auch wie ich per Checkboxen mehrere Registry Keys sichern kann. ABer wie müßte man das ganze nun angehen, das das dann in die jeweiligen Unterordner gespeichert wird?

    Ich wäre Dir für jede Hilfe dankbar!



  • du gibst eigentlich nur einen anderen Dateinamen bei RegSaveKey an, entweder den vollständigen inklusive Laufwerk und Unterverzeichnissen, oder einen relativen, der dann ausgehend vom aktuellen Programmverzeichnis angegeben wird.

    MfG



  • Hallo,
    danke erst mal für Deine schnelle Reaktion.
    Wenn ich Dich also richtig verstanden habe, dann wird dieser Code:

    // Save registry subkey.  If the registry is remote, files will 
            // be saved on the remote machine 
            rc=RegSaveKey(hKeyToSave, szSaveFileName, NULL);
    

    durch diesen hier ersetzt:

    // Save registry subkey.  If the registry is remote, files will 
            // be saved on the remote machine 
            rc=RegSaveKey(hKeyToSave, "C:\\Sicherung_Reg\\", NULL);
    

    Aber dann habe ich ja das Problem, das es nur eine Ordner Angabe ist, und keine Unterordner Angabe für jeden einzelnen Key. Das habe ich nämlich noch nicht so ganz verstanden, oder ich müsste hingehen und den gesamten Code in immer veränderter Form zu wiederholen, aber das kann es ja nicht sein, denke ich. Also wäre nochmal für einen weiteren Tipp dankbar!



  • du kannst doch statt der festen Pfad-Angabe "C:\\Sicherung_Reg\" auch eine Variable einsetzen, und die bekommt eben je nachdem, was der Benutzer gewählt hat, vor dem RegSaveKey-Aufruf einen anderen Wert. Dazu solltest du die Funktionen um Argumente (z.B. den Dateinamen) erweitern, und , wie ich schon geschrieben habe, auch vereinfachen, wenn es geht.

    MfG



  • Hallo,

    okay das habe ich schon mal ein wenig verstanden. Jetzt ist es aber so, das man auch mehrere Checkboxen auf einmal anklicken kann und man nun natürlich immer einen neuen Unterordner benötigt. Da sehe ich mein Problem. Oder wäre das dann ungefähr so zu lösen, das man um den Regsavekey Aufruf eine Schleife setzt und dann gegebenenfalls die Unterordner geändert werden?

    Danke für Deine Unterstützung!



  • ja, das ist ein typsicher Fall für eine Art Schleife, erst die Checkboxen prüfen, und dann entweder bei jedem Durchlauf den oder die entsprechenden neuen Unterordner erstellen, oder, auch möglich, erst einmal nur die Daten der Checkboxen sammeln, und in einer zweiten Schleife die Daten wirklich exportieren (und die entsprechenden Ordner bei jedem Durchlauf erstellen). (Man könnte z.B. bei jedem Klick auf eine Checkbox den entsprechenden Variablen-Inhalt für Ordner und Key schon in eine Art Liste schreiben, bzw. auch wieder entfernen, falls der Haken entfernt wird, dann wird schon während der Benutzer die Auswahlen trifft, eine entsprechende Liste erzeugt, die dann nur noch in einer nachfolgenden Verarbeitungsschleife z.B. nach Button-Klick abgearbeitet wird). Wenn deine Fragen ganz anders werden, und nicht mehr so direkt zum Ursprungs-Thema passen, dann solltest du vielleicht auch mal eine neue Frage aufmachen hier im Forum mit dem speziellen neuen Problem, denn immerhin sind es jetzt schon 53 Beiträge in diesem Thema....

    MfG



  • Hallo Probe-Nutzer,

    ich habe noch einmal eine Frage bezüglich des Setzen des Debuggers. Er bringt mir leider immer noch die Meldung REgenumKeyex und exportiert keine Daten. Da hattest Du mir gesagt ich soll den Debug Modus starten um dann genauere Fehlerauskunft geben zu können.

    Wie setze ich diesen Debug?

    Danke!



  • du setzt in der Zeile:

    return (DWORD) rc;
    

    einen Haltepunkt (Rechtsklick->"Haltepunkt einfügen"), dann das Programm im Debug-Modus starten, und den Fehler wieder herbeiführen. Dann hält das Programm in dieser Zeile, und du kannst den Fehler-Code in rc lesen (Mauszeiger über Variable rc halten). Diese Zahl kannst du dann in dieser Aufstellung hier

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp

    suchen, und damit den Fehlergrund ermitteln.

    MfG



  • Hallo,

    danke für Deine schnelle Hilfe.
    er bringt mir den Fehlercode 6 und dies bedeutet laut den System Error Codes folgendes:

    6 The handle is invalid. ERROR_INVALID_HANDLE

    Was sagt mir das jetzt aus? Wäre nett, wenn DU mir dazu was sagen könntest.



  • jetzt mußt du einfach nur "rückwärts" gehen, woher kommt das Handle? Es kann ja nur das sein, welches RegEnumKeyEx übergeben wird. Also mußt du nur zurückverfolgen, welche Funktion hier ein ungültiges Handle geliefert hat, mit der selben Debug-Methode. Frage von allen wichtigen Funktionen im Debug-Modus den Rückgabe-Wert ab, und du wirst feststellen, wo dein Fehler liegt (nämlich an der Stelle, an der das Handle ermittelt wird, diese Funktion schlägt fehl, wahrscheinlich stimmt der Registry-Pfad nicht oder ähnliches..)

    MfG



  • Also,
    ich habe jetzt noch mal geschaut und leider keine anderen Fehlercodes mitgeteilt bekommen. Wäre nett, wenn Du mal über den Code drüber gucken könntest, den ich momentan verwende. Das wäre echt eine große Hilfe, die Du mir da leistest.

    LONG SaveRegistrySubKey( 
        HKEY hKey,              // handle of key to save 
        LPTSTR szSubKey,        // pointer to subkey name to save 
        LPTSTR szSaveFileName   // pointer to save path/filename 
        ) 
    { 
        HKEY hKeyToSave;    // Handle of subkey to save 
        LONG rc;            // result code from RegXxx 
        DWORD dwDisposition; 
    
        if((rc=RegCreateKeyEx(hKey, 
                              szSubKey, // Name of subkey to open 
                              0, 
                              NULL, 
                              REG_OPTION_BACKUP_RESTORE, // in winnt.h 
                              KEY_QUERY_VALUE, // minimal access 
                              NULL, 
                              &hKeyToSave, 
                              &dwDisposition) 
                              ) == ERROR_SUCCESS) 
        { 
            // Save registry subkey.  If the registry is remote, files will 
            // be saved on the remote machine 
            rc=RegSaveKey(hKeyToSave, szSaveFileName, NULL); 
    
            // close registry key we just tried to save 
            RegCloseKey(hKeyToSave); 
        } 
    
        // return the last registry result code 
        return rc; 
    }  
    
    DWORD SaveReg(HKEY hKey) 
    { 
       TOKEN_PRIVILEGES tp; 
       HANDLE hToken; 
       LUID luid; 
       LONG rc;     // contains error value returned by Regxxx() 
    
       DWORD dwSubKeyIndex=0;   // index into key 
       char szSubKey[_MAX_FNAME]; // this should be dynamic. 
                                // _MAX_FNAME is good because this 
                                // is what we happen to save the 
                                // subkey as 
       DWORD dwSubKeyLength=_MAX_FNAME; // length of SubKey buffer 
    
        if(!OpenProcessToken(GetCurrentProcess(), 
                            TOKEN_ADJUST_PRIVILEGES, 
                            &hToken )) 
        { 
            AfxMessageBox("OpenProcessToken"); 
            return GetLastError(); 
        } 
    if(!LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &luid)) 
    
        { 
            AfxMessageBox("LookupPrivilegeValue"); 
            return GetLastError(); 
        } 
    
        tp.PrivilegeCount           = 1; 
        tp.Privileges[0].Luid       = luid; 
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    
        AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 
                                    NULL, NULL ); 
    
        if (GetLastError() != ERROR_SUCCESS) 
        { 
            AfxMessageBox("AdjustTokenPrivileges"); 
            return GetLastError(); 
        } 
    
    	while((rc=RegEnumKeyEx( 
                            hKey, 
                            dwSubKeyIndex, 
                            szSubKey, 
                            &dwSubKeyLength, 
                            NULL, 
                            NULL, 
                            NULL, 
                            NULL) 
                            ) != ERROR_NO_MORE_ITEMS) { // are we done? 
    
        if(rc == ERROR_SUCCESS) 
       { 
            LONG lRetVal; // return value from SaveRegistrySubKey 
    
            // save registry subkey szSubKey to filename szSubKey 
            if( (lRetVal=SaveRegistrySubKey(hKey, szSubKey, szSubKey) 
                ) != ERROR_SUCCESS) 
            { 
                AfxMessageBox("SaveRegistrySubKey"); 
                return (DWORD) lRetVal; 
            } 
    
            // increment index into the key 
           dwSubKeyIndex++; 
    
           // reset buffer size 
            dwSubKeyLength=_MAX_FNAME; 
    
            // Continue the festivities 
            continue; 
        } 
        else 
       { 
           // 
           // note: we need to watch for ERROR_MORE_DATA 
           // this indicates we need a bigger szSubKey buffer 
           // 
            AfxMessageBox("RegEnumKeyEx"); 
            return (DWORD) rc; 
       } 
    
        } // RegEnumKeyEx 
    
        // Revoke all privileges this process holds (including backup) 
        AdjustTokenPrivileges( hToken, TRUE, NULL, 0, NULL, NULL); 
    
        // close handle to process token 
        CloseHandle(hToken); 
    
        return 0; 
    
    } 
    
    void CRegistryneuDlg::OnButton1() 
    {
    
    UpdateData(TRUE);
    if (m_check1 == TRUE) 
    
    { 
    
    	HKEY hkey; 
    
        DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",0, KEY_ALL_ACCESS, &hkey); 
    
        SaveReg(hkey); 
    
        RegCloseKey(hkey);  
    
    }
    
    else
    
    MessageBox("Der gewünschte Registry Key wurde nicht exportiert!", "Registry Key Export"); 
    
    }
    


  • nun ja, schau dir doch mal den Unterschied an, zu dem, was schon funktioniert hat:

    DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion",0, KEY_ALL_ACCESS, &hkey);
    

    mit deiner Version:

    DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",0, KEY_ALL_ACCESS, &hkey);
    

    ich glaube, du weißt, auf was ich hinaus will. 😉

    MfG


Anmelden zum Antworten