Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Registry durchsuchen (https://www.delphipraxis.net/114125-registry-durchsuchen.html)

Aurelius 20. Mai 2008 07:14


Registry durchsuchen
 
Hi DPler :hi:

Wie einige von euch vielleicht wissen arbeite ich gerade an einem Registry-Editor. Nun stellt sich mir beim Suchalgorithmus die Frage: Soll der komplette Pfad durchsucht werden (HKCU\...\...\Test) oder nur der Name des Schlüssels (Test)? Mich interessiert mal eure Meinung dazu :stupid:

Vielleicht könnt ihr auch gleich eure Meinung dazu schreiben: http://www.delphipraxis.net/internal...185&highlight=

alzaimar 20. Mai 2008 09:35

Re: Registry durchsuchen
 
Nur im Blatt, denn im Pfad hast Du es entweder schon gefunden oder es ist uninteressant (Wenn Du z.B. nur in einem Unterbaum suchen willst).

Aurelius 20. Mai 2008 09:52

Re: Registry durchsuchen
 
Das habe ich mir so auch überlegt, aber in vielen anderen Editoren wird ja der komplette Pfad durchsucht. Außerdem soll der Suchalgorithmus auch reg. Ausdrücke unterstützen...

Phoenix 20. Mai 2008 10:10

Re: Registry durchsuchen
 
Sinnig (und vom User in aller Regel gewünscht) ist: Ab der aktuellen Position rekursiv nach unten durch.
Man wünscht sich aber ggf. eine Option "Alles durchsuchen" zum anhaken, die dann halt oben im Hive anfängt zu suchen.

Aurelius 20. Mai 2008 15:58

Re: Registry durchsuchen
 
das ganze wird schon rekursiv durchsucht. Ich meinte damit ob der gesamte Pfad + Name geprüft werden soll oder nur der eigentl. Name des Schlüssel

bitsetter 20. Mai 2008 18:18

Re: Registry durchsuchen
 
Hi,

ab dem selektierten Item würde ich alles rekursiv durchsuchen. Angenommen das Item "Software" von "Arbeitsplatz\HKEY_CURRENT_USER\Software\Borland\D elphi" ist markiert, dann würde durch die Rekursion auch der Schlüssel "Borland" und "Delphi" mit dem Suchbegriff verglichen werden.

Der Benutzer sollte natürlich noch die Möglichkeit haben, je nach Auswahl die Schlüssel Werte und Daten extra oder auch kombiniert durchsuchen zu können.

Aurelius 21. Mai 2008 17:11

Re: Registry durchsuchen
 
Es wird doch rekursiv durchsucht :D

Beispiel: ich suche nach "Test", es gibt folgenden Schlüssel mit Unterschlüsseln:
HKCU\Software\Test
HKCU\Software\Test\Eins
HKCU\Software\Test\Zwei

Soll es jetzt so sein, dass er
a.) alle 3 "findet", diese also im Gefunden-Fenster angezeigt werden (da ich ja den gesamten Pfad überprüfe)
oder
b.) er nur den 1. Schlüssel auflistet, da dort nur der eigentl. Schlüsselname überprüft wird

Durchsucht werden trotzdem rekursiv alle Schlüssel, keine Frage!

bitsetter 21. Mai 2008 17:45

Re: Registry durchsuchen
 
Na b, 1 mal reicht doch.

alzaimar 25. Mai 2008 20:45

Re: Registry durchsuchen
 
Genau, aber eben anzeigen, das 'Test' ein Unterbaum ist.

Schwedenbitter 10. Feb 2014 14:09

AW: Registry durchsuchen
 
Da ich bislang nirgends im www eine für mich nachvollziehbare Anleitung für das rekursive Duchsuchen der Registry gefunden habe, habe ich mich selbst versucht. Bislang leider ohne Erfolg.

Meine Theorie war die, dass ich ausgehend von den jeweiligen Roots (HKEY_CURRENT_USER etc.) rekursiv nach den Keys mit
Delphi-Quellcode:
TRegistry.GetKeyNames(TStringList);
suche und diese dann wiederum ebenso abklappere. So einfach scheint es aber nicht zu sein. Jedenfalls funktioniert der folgende Code nicht und ich hoffe, mir kann jemand auf die Sprünge helfen, warum das so ist:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  Procedure GetSubKeys(Const SubKey: String; aReg: TRegistry);
  Var
    lList  : TStringList;
    S      : String;
  Begin
    lList:=TStringList.Create;
    Try
      aReg.OpenKeyReadOnly(SubKey);
      aReg.GetKeyNames(lList);
      While (lList.Count > 0) Do
      Begin
        S:=lList.Strings[0];
        ListBox1.Items.Append(S);
        If (SubKey <> '') Then S:=SubKey + '\' + S;
        GetSubKeys(S, aReg);
        lList.Delete(0);
      End;
    Finally
      lList.Free;
    End;
  End;

Var
  lReg     : TRegistry;
begin
  lReg:=TRegistry.Create(KEY_READ);
  Try
    lReg.RootKey:=HKEY_CURRENT_USER;
    GetSubKeys('', lReg);
  Finally
    lReg.Free;
  End;
end;
Und Entschuldigung, dass ich das Thema wieder aufwecke. Wenn ich was funktionierendes und übersichtliches hinbekomme, kann das evtl. ja auch mal in die CodeLib???

Gruß, Alex

baumina 10. Feb 2014 14:24

AW: Registry durchsuchen
 
Funktioniert das hier evtl.?

http://www.swissdelphicenter.ch/de/showcode.php?id=1176

Schwedenbitter 11. Feb 2014 09:08

AW: Registry durchsuchen
 
Ja. Das sieht schon einmal sehr gut aus. 2 Sachen fehlen aber noch bzw. sind fehlerhaft, soweit es das Anzeigen betrifft:
  1. Es sollte
    Delphi-Quellcode:
    OpenKeyReadOnly('');
    statt
    Delphi-Quellcode:
    OpenKey('', False);
    verwendet werden.
    Zumindest in meinem Windows 8 muss man das sonst zwingend als Administrator laufen lassen. Ein Großteil der Schlüssel wird sonst mangels Rechten nicht angezeigt. Und um das Anzeigen geht es schließlich auch in dem Code-Beispiel. (Unter XP fällt das natürlich nicht auf :lol: )
  2. Und es fehlt für meine Belange noch das "Reinschauen" in die einzelnen Keys. Eine Suche macht ja nur Sinn, wenn man auch dort nachsieht. -> Aber das bekomme ich auch noch hin.
Danke für die schnelle und wirklich hilfreiche Antwort!

DeddyH 11. Feb 2014 09:14

AW: Registry durchsuchen
 
Es sollte auch genügen, die Registry-Instanz mit KEY_READ-Rechten zu erzeugen. Und wenn ich mich recht entsinne gibt es sogar Schlüssel, auf die nicht einmal der Administrator zugreifen kann.

Schwedenbitter 12. Feb 2014 12:57

AW: Registry durchsuchen
 
Danke für Eure Hilfe (auch hier) soweit.

Ich vergleiche die Registry mal mit einem Dateisystem. Wenn ich das richtig verstanden habe, dann sind die keys (
Delphi-Quellcode:
GetKeynames
) die (Unter)Verzeichnisse und die values (
Delphi-Quellcode:
GetValueNames
) die Dateien. In den Values sind dann Werte enthalten. Da ich nach einem String suche, war jetzt meine Idee, die Values zu öffnen und die Werte als String auszulesen.
Das klappt aber irgendwie nicht. Ich suche nach einem Wert, der definitiv (jedenfalls lt. regedit) vorhanden ist und er wird trotzdem nicht gefunden.

Aktuell sieht mein Code jetzt so aus:
Delphi-Quellcode:
Procedure TMainForm.SearchReg;
Var
   SearchStr   : String;

   Procedure EnumAllKeys(hkey: THandle; Const RPath: String);
   Var
      KeyList   : TStringList;
      ValList   : TStringList;
      n         : Integer;
      S, T      : String;
      lReg      : TRegistry;
   Begin
      With TRegistry.Create Do
      Try
         RootKey:=hkey;
         OpenKeyReadOnly(EmptyStr);
         KeyList:=TStringList.Create;
         ValList:=TStringList.Create;
         Try
            GetKeynames(KeyList);
            GetValueNames(ValList);
            CloseKey;
            For n:=0 To Pred(ValList.Count) Do   // Einträge durchgehen
            Begin
               S:=ValList[n];
               If Pos(SearchStr, UpperCase(S)) > 0 Then
                  LBRegistry.Items.Append('[val] ' + RPath + '\' + S);

               lReg:=TRegistry.Create;            // Einträge selbst auslesen
               Try
                  lReg.RootKey:=hkey;
                  T:=lReg.ReadString(RPath + '\' + S);
                  If Pos(SearchStr, UpperCase(T)) > 0 Then
                     LBRegistry.Items.Append('[con] ' + RPath + '\' + S + '=' + T);
                  Finally
                  lReg.Free;
               End;
            End;

            For n:=0 To Pred(KeyList.Count) Do   // weitere Keys suchen
            Begin
               S:=KeyList[n];
               If Pos(SearchStr, UpperCase(S)) > 0 Then
                  LBRegistry.Items.Append('[key]' + RPath + '\' + S);
               If OpenKeyReadOnly(S) Then
               Begin
                  EnumAllKeys(CurrentKey, RPath + '\' + S);
                  CloseKey;
               End;
            End;
         Finally
            KeyList.Free;
            ValList.Free;
         End;
      Finally
         Free;
      End;
   End;

Begin
   SearchStr:=UpperCase(EDSearch.Text);
   LBRegistry.Items.Clear;
   LBRegistry.Items.BeginUpdate;
   Try
//   EnumAllKeys(HKEY_CLASSES_ROOT   ,'');
//   EnumAllKEys(HKEY_CURRENT_USER   ,'');
      EnumAllKEys(HKEY_LOCAL_MACHINE  ,'');
//   EnumAllKEys(HKEY_USERS          ,'');
//   EnumAllKEys(HKEY_PERFORMANCE_DATA,'');
//   EnumAllKEys(HKEY_CURRENT_CONFIG ,'');
//   EnumAllKEys(HKEY_DYN_DATA       ,'');
   Finally
      LBRegistry.Items.EndUpdate;
   End;
End;

DeddyH 12. Feb 2014 13:09

AW: Registry durchsuchen
 
Irgendwie scheint da ein lReg.OpenKey zu fehlen, oder habe ich es nur übersehen? So suchst Du ja im Wurzelknoten nach einem Eintrag, dessen Name sich aus
Delphi-Quellcode:
RPath + '\' + S
ergibt.

Volker Z. 12. Feb 2014 23:33

AW: Registry durchsuchen
 
Hallo,

Zitat:

[...] Das klappt aber irgendwie nicht. Ich suche nach einem Wert, der definitiv (jedenfalls lt. regedit) vorhanden ist und er wird trotzdem nicht gefunden.
Naja, wenn regedit sagt, dass der Wert in der Registry steht, dann wird das schon so sein; wenn Dein Programm den Wert nicht findet liegt es wohl an Deiner Programmierung.

Zitat:

Aktuell sieht mein Code jetzt so aus:
Und da haben wir es schon:
  1. Du versuchst einen Wurzelknoten (EmptyString) zu öffnen (was nur [in Deinem Fall] bei HKEY_LOCAL_MACHINE klappt, ansonsten raus aus der procedure)
  2. Du liest alle Unterschlüssel ein (KeyList)
  3. Du liest alle Wertebezeichner ein (ValueList)
  4. Du schließt den geöffneten Schlüssel
  5. Du versuchst auf Daten eines geschlossenen Schlüssels zuzugreifen (was nicht funktioniert)
  6. Du gehst (nicht über Los, sondern direkt) mit dem aktuellen CurrentKey (da der bereits geschlossen wurde und 0 ist) zu Schritt 1. (das funktioniert aber nicht, himitsu und meinereiner hatten das aber schon gesagt)
Da wundert es nicht, dass Du nix findest!

Zu 1.: Wenn Du nur in einen bestimmten Hauptschlüssel (z. B. HKEY_LOCAL_MACHINE) suchen möchtest, dann kannst Du das konstant gestalten, ansonsten immer den Hauptschlüssel als Parameter übergeben
Zu 2.: Warum zwei Listen, wenn es in diesem Fall auch mit einer geht?
Zu 3.: Dito
Zu 4.: Lass das bleiben
Zu 5.: Dito
Zu 6.: Lass CurrentKey weg (entweder konstant oder den Hauptschlüssel per Parameter, den "Pfad" oder Unterschlüssel relativ übergeben)

In Code gegossen vielleicht so (Hauptschlüssel per Parameter):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   SearchString : string;

   procedure EnumAllKeys (const Root : HKEY; const Key : string);
   var
     r : TRegistry;
     l : TStringList;
     i : Integer;
     s : string;
   begin
     r := TRegistry.Create;
     l := TStringList.Create;
     try
       r.RootKey := Root;

       if r.OpenKeyReadOnly (Key) then
         begin
           r.GetValueNames (l);
           for i := 0 to l.Count - 1 do
             begin
               s := l [i];
               if Pos (SearchString, UpperCase (s)) > 0 then
                 ListBox1.Items.Add ('[val] ' + r.CurrentPath + '\' + s);

               if r.GetDataType (s) in [rdString, rdExpandString] then
                 begin
                   s := r.ReadString (s);
                   if Pos (SearchString, UpperCase (s)) > 0 then
                     ListBox1.Items.Add ('[con] ' + r.CurrentPath + '\' + s)
                 end
             end;

           r.GetKeyNames (l);
           for i := 0 to l.Count - 1 do
             begin
               s := l [i];
               if Pos (SearchString, UpperCase (s)) > 0 then
                 ListBox1.Items.Add ('[key] ' + r.CurrentPath + '\' + s);

               EnumAllKeys (Root, r.CurrentPath + '\' + s)
             end
         end
     finally
       r.Free;
       l.Free
     end
   end;

begin
   SearchString := 'PRINT';
   EnumAllKeys (HKEY_CURRENT_CONFIG, '')
end;
Vielleicht hilft 's

Gruß

Schwedenbitter 13. Feb 2014 12:41

AW: Registry durchsuchen
 
Zitat:

Zitat von Volker Z. (Beitrag 1247672)
...
Vielleicht hilft 's

Perfekt! Danke.
Vielleicht sollte man das noch in die Code Library übernehmen. In der Kürze und Vollständigkeit ist das meines Erachtens sehr hilfreich und ich habe das in vergleichbarer Form im Netz nirgends gefunden.

himitsu 13. Feb 2014 15:58

AW: Registry durchsuchen
 
Zitat:

Zitat von Volker Z. (Beitrag 1247672)
Naja, wenn regedit sagt, dass der Wert in der Registry steht, dann wird das schon so sein; wenn Dein Programm den Wert nicht findet liegt es wohl an Deiner Programmierung.

Oder an den "Umleitungen" des Systems.

Werden für 32-Bit-Programme Umleitungen eingerichtet, damit die im Win64 ihr Zeug an den "gewohnten" 32-Bit-Orten finden.




Irgendwie spinnt TeamViewer grad. (in 1-2 Stündchen dann)
Hab daheim eine PAS rumliegen, in der die TRegistry um so paar Funktionen erweitert wurde, wie Umleitungen deaktivieren oder selber Welche setzen oder Arbeiten in 'ner Transaktione usw.
Man kann sich natürlich auch selber entsprechenden WinAPIs raussuchen.

himitsu 15. Feb 2014 00:38

AW: Registry durchsuchen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ups, bevor ich es nochmal vergess'.
TRegistryEx.Reflection, bzw. MSDN-Library durchsuchenRegDisableReflectionKey

Die Funktiononen für's Dateisystem fehlen noch (die alte Implementation gefällt mir nicht mehr) und da sich das schrottige TRegistry nicht "überschreiben" läßt, ist diese Implementation auch nich ganz ideal.

juergen 15. Feb 2014 12:41

AW: Registry durchsuchen
 
Hallo,
Hinweis: es fehlt noch ein UPPERCASE beim Searchstring, wenn man es verallgemeinern will

Delphi-Quellcode:
begin
    SearchString := UPPERCASE('PRINT');  // <====
    EnumAllKeys (HKEY_CURRENT_CONFIG, '')
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz