Registryschlüssel löschen
-
nunja ... wollt ich ja auch nun machen, dass problem ist aber, dass ich mit dem Typ TRegKeyInfo Sorgen habe.
wenn ich diesen Code erstmal nehme
TRegistry *pReg = new TRegistry; AnsiString DelKey; DelKey = "\\Software\\L+P\\Reports\\"; TRegKeyInfo *wert = new TRegKeyInfo; try { pReg->RootKey = HKEY_CURRENT_USER; if (pReg->KeyExists(DelKey)) { if (pReg->OpenKey(DelKey,false)) { pReg->GetKeyInfo(&wert); //Hier Fehlermeldung cout << wert //Ausgabe? } else cout<<"Key konnte nicht geöffnet werden"<<endl; } else cout<<"Key existiert nicht"<<endl; } catch(...) { ; } delete wert; delete pReg; }
dann habe ich (an der kommentierten stelle) Fehlermeldungen:
*[C++Fehler] reg2.cpp(73): Cannot convert 'Registry::TRegKeyInfo * *' to 'Registry::TRegKeyInfo'.
[C++Fehler] reg2.cpp(73): Type mismatch in parameter 'Value' in call to '_fastcall Registry::TRegistry::GetKeyInfo(Registry::TRegKeyInfo &)'.
*Wie muss ich den Typ deklarieren und vor allem wie kann ich "wert" dann auch ausgeben bzw. auswerten? Denn es gibt ja mehrere Sachen zurück. die Hilfe gibt nicht wirklich viel dazu her.
mfg
-
schau dir nochmals genau den Aufruf von GetKeyValue() an.
Vielleicht könnte dies noch eine Möglichkeit sein, die Unterschlüssel zu löschen: (hab ich in der BCB-Hilfe gesehen)
Da gibt es eine Eigenschaft namens Access. Setz diese Eigenschaft mal vor dem OpenKey auf KEY_ALL_ACCESS
-
entweder bin ich blind oder ihr habt ne andere Hilfe als ich...
ich habe BCB 3.0 und habe hier für TRegistry die Methoden GetKeyInfo() und GetKeyNames(). Mit GetKeyInfo würde das gehen, das ist korrekt, aber der Prototyp lautet:
bool __fastcall GetKeyInfo(TRegKeyInfo &Value);
und ich egal wie ich "Value" deklarieren oder definieren möcht, immer kommen o.g. Fehlermeldungen.
Und ich hab in meiner Hilfe nur den "Artikel" zu den oben genannten Methoden der TRegistry und da ist weder ein Hinweis auf eine Methode Access noch ein Beispiel. Welchen Builder benutzt ihr denn?
*komischguck*mfg
[ Dieser Beitrag wurde am 25.11.2002 um 13:51 Uhr von skho editiert. ]
Nachtrag: Habe erstmal rausgefunden wie ich TRegKeyInfo deklariere (einfach vor die Funktion folgendes geschrieben):
Registry::TRegKeyInfo wert;
nun stellt sich die Frage, wie kann ich auf die Unterschiedlichen Werte in "wert" nun zugreifen, dazu steht nun wirklich überhaupt nichts in der Hilfe (zu mindest in meiner) Anregungen wären gut... dann dürfte die Schleife auch keine Problem mehr darstellen.
[ Dieser Beitrag wurde am 25.11.2002 um 13:58 Uhr von skho editiert. ]
-
also ich hab hier den BCB 5 Enterprise Edition.
Die Eigenschaft Access legt die Zugriffsebene beim Öffnen von Schlüsseln fest.
__property long Access = {read=FAccess, write=FAccess};
Die Methode gibt Informationen über den aktuellen Schlüssel zurück.
struct TRegKeyInfo
{
int NumSubKeys;
int MaxSubKeyLen;
int NumValues;
int MaxValueLen;
int MaxDataLen;
_FILETIME FileTime;} ;
bool __fastcall GetKeyInfo(TRegKeyInfo &Value);
-
Hallo
Wenn du es über die WinAPI lösen bist, bist du hier eigentlich im falschen Teil des Forums. Vieleicht können sie dir im WinAPI-Forum besser weiter helfen.
Wenn du TRegistry - also die BCB-Klasse benutzt, kannst du zum Auslesen GetKeyNames benutzen. GetKeyNames speichert alle Unterschlüssel in eine Stringliste, deren Strings du dann einzeln abarbeiten müstest. Diese mußt du natürlich auch wieder auf Unterschlüssel prüfen.
Diese Vorgehensweise sollte eigentlich übersichtlicher sein, wenn auch langsamer, da sich TRegistry der WinAPI-Funktionen bedient
-
hi,
sorry @maloo aber ich muss dich eines besseren belehren ! unter 95/98/ment/2000/xp löschen wir vor der installation alle vorhanden verzeichnisse und regeinträge !
ich habe es auch schwarz auf weiss !
nichts für ungut !
ciao
-
habe jetzt gerade noch mal in die sdk gesehen und da steht explizit, das man das machen kann, nur müssen vorher alle untereinträge gelöscht sein. das kann doch nicht so schwierig sein!
Windows NT/2000/XP: The subkey to be deleted must not have subkeys. To delete a key and all its subkeys, you need to recursively enumerate the subkeys and delete them individually. To recursively delete keys, use the SHDeleteKey function.
___SHDeleteKey___
und wenn du das mit tregistry machen willst, solltest du den key vorher wieder schliessen (closekey). schonmal erlebt, das man unter windows was geöffnetes löschen kann?
-
nun ja ... GetKeyNames benutze ich auch. Hab nur noch ne Frage bezüglich der Anzahl der Ebenen. Ich meine ich weiß vorherein ja nicht, wie tief die Schlüssel verzweigt sind, naja könnt ich auch irgendwie wieder mit GetKeyInfo überprüfen... *grübel* ... naja werd mich mal ransetzen, falls einer noch was zwingendes und wichtiges hat, erbitte ich eine kleine Meldung *g* ansonsten
Dank ich erstmal allen.
Vielleicht stellt ihr das ganze hier mal in die FAQ.mfg
Steffen
-
Hi,
wollte nur mitteilen, dass es nun endlich funktioniert. habe rekursiv nach den Unterschlüsseln gesucht und nun funzt es, gott sei dank.
ich dank allen mitwirkenden
werde mich dann mal wieder dem schreiben von registryeinträgen zuwenden, aber ich denke dass das nicht so schwierig ist, erste versuche haben ja schon geklappt.Also dank nochmal.
mfg
-
Hallo!
Unter Windows 2000 Pro mit BCB 5 funktioniert folgender Code perfekt:
#include <vcl.h> #include <registry.hpp> #include <iostream.h> #pragma hdrstop #pragma argsused void reg_loeschen() { TRegistry *pReg = new TRegistry; //dynamisch Speicherplatz festlegen AnsiString DelKey; DelKey = "\\Software\\L+P\\Reports"; //Schlüssel der gelöscht werden soll try { pReg->RootKey = HKEY_CURRENT_USER; if (pReg->KeyExists(DelKey)) //auf Existenz überpüfen { pReg->OpenKey(DelKey,false); cout<<"Key wird gelöscht!"<<endl; bool erfolg = pReg->DeleteKey(DelKey); //Löschen des Schlüssels if (erfolg == true) { cout<<DelKey.c_str()<<" wurde geloescht"<<endl; } else cout<<DelKey.c_str()<<" konnte nicht geloescht werden"<<endl; } } catch(...) { ; } delete pReg; } int main() { reg_loeschen(); cout << "taste druecken"; getchar(); return 0; }
Übrigens habe ich folgenden Registrycode gelöscht:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\L+P]
[HKEY_CURRENT_USER\Software\L+P\Reports]
[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #1]
[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #1\Neuer Schlüssel #1]
"Neuer Wert #1"="1"
"Neuer Wert #2"=hex:10
"Neuer Wert #3"=dword:00000001[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #2]
[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #2\Neuer Schlüssel #1]
[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #3]
"Neuer Wert #1"="1"
"Neuer Wert #2"=hex:10
"Neuer Wert #3"=dword:00000001[HKEY_CURRENT_USER\Software\L+P\Reports\Neuer Schlüssel #4]
Tschuess
-
@konvenienz: Wenn du deinen Text übersetzt, steht dort drin, dass es nicht funktioniert ohne die Unterschlüssel vorher zu löschen (meine Rede), sondern nur mit rekursiven Schleifenaufruf und einzelnem Löschen der Schlüssel. Das es für das rekursive Löschen eine Funktion gibt, war mir neu. Könntest du mir euer Beispiel zuschicken, damit ich es im BCB-Tutorial unter Registryschlüssel löschen mit einarbeiten kann? Es erfolgt natürlich ein Hinweis auf deine/eure Urheberschaft.
Zum Thema Schlüssel vorher schließen. Hier verwechselst du Windows-Funktionen mit den Win-API Funktionen. Um mit einem Schlüssel zu arbeiten - und sei es nur löschen - mußt du sozusagen die Schublade erst öffnen, in dem das Schlüsselbund liegt und kannst dann einen Schlüssel befeilen oder vom Bund abmachen.
-
@maloo : dein text auf meine antowrt :
"@ konvenienz: Bist du dir sicher, dass ihr es auf einem WindowsNT-System geschafft habt einen Registryschlüssel zu löschen, der Unterschlüssel (nicht Werte!!!) enthielt? Laut Microsoft und meinen eigenen Erfahrungen ist dies unmöglich. Schaue dir in der WindowsSDK-Hilfe mal den Begriff RegDeleteKey an. Dort steht es eigentlich schwarz auf weiss.
Nichts für ungut und noch ein schönes Wochenende wünscht"wo steht in diesem abnschitt das man erst die unterschlüssel löschen muss ????
sorry aber das hast du nicht geschrieben ! nur das es laut sdk unmöglich ist ! und das ist eben nicht unmöglich und steht auch dort nicht drin !!!!!
aber egal ....beispeilcode ...mal sehen diesen code haben wir in eine komerzeille software software eingebaut. ich schau mal was sich da machen lässt.
ciao
-
ist nur gut, dass ich es mittlerweile gelöst habe *g*
Habe übrigens zwei Funktionen und lösche die Unterschlüssel rekursiv... Sicherlich finden sich Ansatzpunkte zur Optimierung, aber ich bin damit zufrieden... naja ich schreib es halt mal auf. Ist aber ein bissle länger :-))
Er macht das was er soll :-))
hier der Code:
//Registrierungsverzeichnis und -einträge aus /Reports/ löschen //Schleifenfunktion bool schleife(AnsiString &SubKey) { bool erfolg = true; bool geoeffnet; TRegistry *pReg = new TRegistry; //dynamische Speicherreservierung für Registrypointer TStringList *Keyname = new TStringList; //dynamische Speicherreservierung für StringListzeiger Registry::TRegKeyInfo Info; //Typ definition für Schlüsselinformationen AnsiString DelKey; try //Exeptionsabfangen try , catch { geoeffnet = pReg->OpenKey(SubKey,false); //Oeffnen des Unterschlüssels DelKey = SubKey; //zwischenspeicherung des Unterschlüssels if (geoeffnet == true) //ist Unterschlüssel geöffnet { //Unterschlüssel ist geöffnet if (pReg->HasSubKeys()) //hat Unterschlüssel Unterschlüssel { //Unterschlüssel hat Unterschlüssel pReg->GetKeyInfo(Info); //Hole Schlüsselinformationen pReg->GetKeyNames(Keyname); //Hole Schlüsselnamen int lauf; for (lauf=0;lauf<=Info.NumSubKeys-1;lauf++) //läuft bis (Anzahl der Schlüssel)-1,da String ab 0 beginnt { SubKey = Keyname->Strings[lauf]; //Name pro Zeile der Liste SubKey = DelKey + SubKey + "\\"; //kompletter Schlüsselpfad schleife(SubKey); //rekrusiver aufruf, falls Unterschlüssel, } //noch Unterschlüssel hat schleife(DelKey); //nach Beendigung, rekurvsiver Aufruf,damit oberster } //Unterschlüssel auch gelöscht werden kann else //hat keine Unterschlüssel { pReg->CloseKey(); //aktuellen Schlüssel schließen erfolg = pReg->DeleteKey(SubKey); //aktuellen Schlüssel löschen } } } catch (...) //Exeptionbehandlung { ; } delete Keyname; //Löschen des dynamischen Speicherplatzes der StringListe delete pReg; //Löschen des dynamischen Speicherplatzes des Registryzeigers return(erfolg); //booleanscher Rückgabewert der Funktion } //Loeschfunktion bool reg_loeschen() { TRegistry *pReg = new TRegistry; //dynamischer Speicher für Registrypointer TStringList *Keyname = new TStringList; //dynamischer Speicher für String-Liste Registry::TRegKeyInfo Info; //Typ definition für Schlüsselinformationen bool erfolg; AnsiString DelKey; AnsiString ToDelKey; AnsiString SubKey; DelKey = "\\Software\\L+P\\Reports"; //Hauptschlüssel try //Exeptions abfangen. { //try-Klammer oeffnen pReg->RootKey = HKEY_CURRENT_USER; //Rootkey auf CURRENT_USER setzen pReg->KeyExists(DelKey); //Existiert der Hauptschlüssel ToDelKey = DelKey + "\\"; if (pReg->OpenKey(ToDelKey,false)) //Hauptschlüssel öffnen für weitere abfragen { if (pReg->HasSubKeys()) //hat der Schlüssel Unterschlüssel? { //Schlüssel hat Unterschlüssel pReg->GetKeyInfo(Info); //Schlüsselinformationen auslesen pReg->GetKeyNames(Keyname); //Schlüsselnamenauslesen int lauf; for (lauf=0; lauf<=Info.NumSubKeys-1;lauf++) //läuft bis Anzahl der Unterschlüssel-1, da { //die stringListe mit 0 anfangen muss, die Anzahl //aber mit 1 beginnt SubKey = Keyname->Strings[lauf]; //String jeder zeile SubKey = ToDelKey + SubKey + "\\"; //kompletter Baumpfad erfolg = schleife(SubKey); //Aufruf der Schleifenfunktion } if (erfolg == true) //bei Erfolg (alle Unterschlüssel zu "Reports" { //sind gelöscht) erfolg = reg_loeschen(); //rekursiver aufruf der Funktion um den Schlüssel } //"Reports" auch zu löschen } else //Schlüssel hat keine Unterschlüssel { pReg->CloseKey(); //schließe Hauptschlüssel erfolg=pReg->DeleteKey(ToDelKey); //lösche hauptschlüssel } } } //try-Klammer geschlossen catch(...) // abfangen von Exeptions { ; } delete Keyname; //Lösche Dynamischen Speicher der StringListe delete pReg; //Lösche Dynamischen Speicher des Registryzeigers return (erfolg); //booleanscher Rückgabe der Funktion } int main() { TRegistry *pReg = new TRegistry; AnsiString MainKey; AnsiString ReportKey; MainKey = "\\Software\\L+P"; ReportKey = MainKey + "\\Reports"; bool geloescht; pReg->RootKey = HKEY_CURRENT_USER; if (pReg->KeyExists(ReportKey)) { geloescht = reg_loeschen(); if (geloescht== true) { cout<<"Die Registry wurde geloescht!"<<endl; } else { cout<<"Die Registry wurde nicht geloescht!"<<endl; } } else cout<<"ReportsKey wurde bereits geloescht"<<endl; cout << "taste druecken"; getchar(); return 0; }
@maloo kannst ihn ja leicht verändern (bzw. allgemeiner machen) und ihn auf deiner Seite aufnehmen
mfg
-
@konvinienz: Da haben wir wohl konstruktiv aneinander vorbei geredet. Ist ja auch nicht so wild, da ja eine Lösung gefunden wurde und ich für meinen Teil etwas dazugelernt habe (Befehl für das rekursive Löschen).
An dieser Stelle mal ein Danke Schön für den Quelltext.
Kommt natürlich mit Quellenangabe ins Tutorial auf meiner Page. Vielleicht kürzt Junix oder Jansen das Thema auch auf das wesentliche und schiebt es hier in die FAQ !?
-
Nur noch ein kurzer Hinweis:
Mein abgeänderter Code von gestern funktioniert auch unter NT 4.0 SP5.
(Kompiliert mit BCB 5 Pro)
Eventuell ist der ganze Aerger ein Problem, hervorgerufen durch die ältere BCB-Version.
Oder von MS:
Ich hatte kuerzlich das Problem, das der Registrycode einer Anwendung auf genau zwei NT4-Maschinen nicht lief. Auf anderen (Identische Version/SP) aber keine Probleme machte.Tschuess
-
@Barnie: Waren die Nutzerrechte auch überall gleich - wäre ja mal interessant, ob die Windows-SDK dahingehend etwas verschweigt.
-
Auf dem Win2k System war ich Admin. (User hab ich da nicht getestet.)
Unter WinNT war ich nur User.Tschuess
-
und wie löscht man einen einzelnen string, z.b. unter "run"? ich will ja nich den ganzen ordner "run" löschen
-
Was heisst Löschen auf Englisch?
Und was für TRegistry-Methoden mit entsprechendem Namen gibt's noch?
-
hast du kein wörterbuch? löschen=delete
und ich würd dir DeleteValue vorschlagen
ich hoffe, ich konnte dir helfen