AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Kann mit RegQueryValueEx etc. in Delphi nicht umgehen
Thema durchsuchen
Ansicht
Themen-Optionen

Kann mit RegQueryValueEx etc. in Delphi nicht umgehen

Ein Thema von Chewie · begonnen am 10. Jun 2002 · letzter Beitrag vom 10. Jun 2002
Antwort Antwort
Seite 1 von 2  1 2      
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#1

Kann mit RegQueryValueEx etc. in Delphi nicht umgehen

  Alt 10. Jun 2002, 15:33
Tach zusammen.
Ich bin gerade bei dem Versuch, auf die Registry mit WinAPI-Funktionen zuzugreifen. Schlüssel öffnen klappt ja soweit ohne Probleme, aber beim Auslesen haperts. Ich benutze die Funktion RegQueryValueEX; der Rückgabewert zeigt mir an, dass es keinen Fehler gab. Allerdings hab ich in den Variablen, die ich laut PSDK zurückkriegen sollte, keine Werte gehabt. Ich hab mir die Funktionsimplementierung in der windows.pas mal angeschaut, und da siehts so aus:

Code:
function RegQueryValueEx(hKey: HKEY; lpValueName: PChar;
  lpReserved: Pointer; lpType: PDWORD; lpData: PByte; lpcbData: PDWORD): Longint; stdcall;
Laut PSDK sind aber die letzten drei Variablen Referenzen und nicht nur Parameter, aber da müsste, zumindest anhand meiner ObjektPascal-Kenntnisse var vor dem Parameternamen gestellt sein. Da dies aber nicht der Fall ist, kann doch auch nach dem Funktionsaufruf kein Wert in den Variablen sein.
Ich hoffe, so weit bin ich richtig. Wenn ja, dann frage ich mich, wie ich aus Delphi Werte aus der Registry lesen kann. Es wäre also wunderbar, wenn mich jemand aufklären würde, wie das geht bzw. kennt jemand vielleicht ein Delphi-Tutorial für die Registry mit der WinAPI? Im Notfall muss ich mir die registry.pas halt mal reinziehen und hoffen, dass ich sie versteh.
Vielen Dank schon im Voraus.
Martin Leim
  Mit Zitat antworten Zitat
Benutzerbild von RomanK
RomanK

Registriert seit: 7. Jun 2002
Ort: Kirchheim unter Teck
1.036 Beiträge
 
Delphi 7 Personal
 
#2
  Alt 10. Jun 2002, 15:50
Hoi das hab ich aus dem EDH, allerdings ist das nicht direkt mit der WinAPI:
Zitat:
Mit der Registry arbeiten


Was ist die Registry?

Die Registry ist die zentrale Datenbank eines Windows-Betriebssystems

In der Registry werden die meisten Einstellungen und Informationen des Betriebssystems gespeichert. Dazu gehören unter anderem der Dateiname des Hintergrundbildes, Informationen über installierte Software und vieles mehr. Diese Werte/Informationen lassen sich ohne große Umstände aus der Datenbank auslesen und abändern.

ACHTUNG! Beachte, dass durch die Manipulation der Registry tief ins System eingegriffen wird. Lege zuvor ein Backup Deiner persönlichen Dateien an, um Datenverlust vorzubeugen.


Eine Instanz des Objektes erstellen

Delphi kapselt den Registryzugriff in einem Objekt namens TRegistry. Es befindet sich in der Unit Registry, welche Du der uses-Klausel hinzufügen musst. Bevor Du mit diesem Objekt arbeiten kannst, musst Du es deklarieren und eine Instanz davon erstellen:
Code:
procedure TForm1.Button1Click(Sender: TObject);
var
  Registry: TRegistry;
begin
  with TRegistry.Create do
Die Registrierungsdatenbank hat einen hierarchischen Aufbau. Am Anfang dieser Hierarchie stehen mehrere Hauptschlüssel, die wiederum weitere Unterschlüssel enthalten. Alle Schlüssel die Deine Anwendung erzeugt, öffnet oder liest sind Unterschlüssel von diesen vordefinierten Hauptschlüsseln. Die Eigenschaft Rootkey definiert diesen Hauptschlüssel für das TRegistry-Objekt. Standardgemäß wird die Eigenschaft Rootkey bei der Erzeugung des Objekts auf den Wert HKEY_CURRENT_USER gesetzt.

Mögliche Werte von Rootkey:
Code:
 
HKEY_CLASSES_ROOT
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
HKEY_PERFORMANCE_DATA
HKEY_CURRENT_CONFIG
HKEY_DYN_DATA

Bevor Du jetzt einen Schlüssel erzeugst oder einen Wert aus einem Schlüssel lesen kannst, muss dieser geöffnet werden. Dies geschieht mit dem Aufruf von Openkey:
Code:
function OpenKey(const Key: string;
  CanCreate: Boolean): Boolean;
Die Funktion erwartet zwei Parameter: Erstens den Schlüssel, welcher geöffnet werden soll (immer relativ von bisher geöffneten Schlüsseln) und zweitens einen booleschen Parameter, welcher steuert, ob ein Schlüssel, wenn er noch nicht existiert erstellt werden soll (True) oder nicht (False). Jeder weitere Aufruf von Openkey öffnet den Schlüssel relativ vom bisher geöffnetem Schlüssel. Bevor man also einen anderen Schlüssel öffnen möchte ist der Aufruf CloseKey; notwendig.



Lesen/Schreiben von Werten

Das Objekt ist jetzt bereit in die Registry Werte zu schreiben und auch aus dieser zu lesen. Dies geschieht mit der Methode WriteString bzw. mit ReadString. Die beiden Parameter, die WriteString erwartet, müssen Sie mit Angaben zum Namen (Typ String) und zum Wert (auch vom Typ String), welcher gespeichert werden soll, füllen. Ist der Name bereits vorhanden, wird dieser überschrieben.

ReadString erwartet nur einen Parameter, nämlich den Namen des zu lesenden Werts. Als Result wird der Wert mit diesem Namen zurückgegeben. Man hat auch die Möglichkeit direkt einen Integer-Wert, einen booleschen Wert oder eine Gleitkommazahl in die Registry zu schreiben/lesen. Für diese Aufgabe gibt es die Methoden WriteInteger, WriteBool und WriteFloat, bzw. ReadInteger, ReadBool und ReadFloat. Die Parameter sind bei diesen Methoden identisch mit Ihren Verwandten WriteString und ReadString. Natürlich muss der übergebene Wert bzw. der Rückgabewert vom entsprechenden Typ sein.

Da für das Objekt Speicher reserviert wurde, muss dieser mit Free wieder freigegeben werden.


Beispiel

Es folgt jetzt ein Beispiel, welches einen String (Edit1.Text) und einen Integer (SpinEdit1.Value) in den Schlüssel "HKEY_CURRENT_USER\Software\TestFirma\TestProd ukt" schreibt. Zur Sicherheit kommt das ganze in einen try-finally-Block.
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TRegistry.Create do
  begin
    try
      Rootkey:=HKEY_CURRENT_USER; //Hauptschlüssel
      OpenKey('Software\TestFirma\TestProdukt',True); //Unterschlüssel öffnen
      WriteString('TestString',Edit1.Text);
      WriteInteger('TestInteger',SpinEdit1.Value);
    finally
      Free;
    end;
  end;
end;
Tipp: Sollte der Eintrag nicht sofort in RegEdit erscheinen, einfach mal F5 drücken.

Das Lesen der Werte aus der Registry ist nicht viel schwieriger. Der Wert "TestString" wird in das Edit-Feld eingelesen und die Integer-Zahl "TestInteger" wird SpinEdit1 übergeben. Zur Speichersicherheit wird das ganze in einem try-finally-Block gekapselt.
Code:
procedure TForm1.Button2Click(Sender: TObject);
begin
  with TRegistry.Create do
  begin
    try
      Rootkey:=HKEY_CURRENT_USER;
      OpenKey('Software\TestFirma\TestProdukt',True);
      Edit1.Text:=ReadString('TestString');
      SpinEdit1.Value:=ReadInteger('TestInteger');
    finally
      Free;
    end;
  end;
end;

Weitere Befehle des Objekts TRegistry

TRegistry bietet noch viele weitere Möglichkeiten, die Registry zu bearbeiten.


Einen Wert löschen (im aktuell geöffnetem Schlüssel):
Code:
DeleteValue('NameDesWertes');
Einen Schlüssel löschen (im aktuell geöffneten Hauptschlüssel - Rootkey):
Code:
DeleteKey('Software\TestFirma\TestProdukt');
Testen, ob ein Schlüssel (relativ vom geöffnetem Schlüssel) oder ein Wert existiert:
Code:
Checkbox1.Checked:=KeyExists('TestProdukt');
Checkbox2.Checked:=ValueExists('TestString');
Weitere Befehle findest Du in der OH unter dem Stichwort "TRegistry". Es ist auch ein sehr ausfürhliches Beispiel dabei. Die Erklärungen sind größtenteils verständlich.
SORRY das ich einfach den ganzen Text poste
Roman Keller
Krieg ist Gottes Art den Amerikanern Geographie beizubringen!
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#3

Leider nicht, was ich meinte

  Alt 10. Jun 2002, 15:57
Danke für die Antwort, aber das ist leider nicht das, was ich gemeint hab. ich will die Registry-Funktionen der WinAPI benutzen, nicht die der TRegistry-Klasse, da die registry.pas meine EXE um knapp 50 kb aufbläht. Wenn schon nonVCL, dann richtig
Martin Leim
  Mit Zitat antworten Zitat
Benutzerbild von RomanK
RomanK

Registriert seit: 7. Jun 2002
Ort: Kirchheim unter Teck
1.036 Beiträge
 
Delphi 7 Personal
 
#4
  Alt 10. Jun 2002, 16:01
Hab ich mir gedacht
Roman Keller
Krieg ist Gottes Art den Amerikanern Geographie beizubringen!
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#5
  Alt 10. Jun 2002, 16:16
Moin Chewie,

was die letzten drei Paramter angeht unterliegst Du einem Irrtum.
Es werden die Adressen übergeben, und somit kann die Funktion an die Stelle auf die diese Pointer verweisen sehr wohl Daten schreiben.
Du bräuchtest var nur, wenn diese Adresse geändert werden soll.
Prinzipiell können bei API Funktionen alle Parameter als Const deklariert werden (mir fällt so auf Anhieb jedenfalls keine Ausnahme ein), da, für den Fall, dass die Funktion über einen der Parameter einen Wert zurückgeben soll dieser als Pointer deklariert ist. (siehe auch oben)

Mal ein kleines stilisiertes Beispiel:

Code:
var
  pBuffer    : Pointer;
  dwValueType : DWord;
  dwBufferLen : DWord;
  hOpenKey   : hKey;

RegQueryValueEx(hOpenKey, PChar('VALUENAME'),nil,@dwValueType,pBuffer,@dwBufferLen)
Die ganzen Initialisierungen habe ich weggelassen.
Kommst Du so damit klar?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#6
  Alt 10. Jun 2002, 16:43
Klar. Ich denk immer noch von "normalen" Variablen und nicht von Pointern. Der Adressbereich bleibt ja konstant. OK. Soweit versteh ich die Funktion.
Jetzt hab ich das Problem, dass der Wert des Registry-Keys ja mit Hilfe des Pointers gespeichert ist. Da ich ja einen Allzweck-Pointer nicht dereferenzieren kann, muss ich ihn erstmal ain einen typisierten Pointer umwandeln und kann ihn dann dereferenzieren. Soweit die Theorie. DA ich aber heute zum ersten Mal überhaupt Pointern arbeite, hab ich keinen blassen Schimmer, wie ich das mache. Wie kann ich einen Pointer z. B. in einen Pointer auf einen String umwandeln?
Martin Leim
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#7
  Alt 10. Jun 2002, 16:50
Moin Chewie,

da hast Du aber Glück, dass ich gerade an einem Reg Editor arbeite

Code:
function RegDataToString(const p_dwRegDataType : DWord;const p_pValueData : Pointer;const p_dwDataLen : DWord) : string;

var
  pRegBinary : PByte;
  pRegDWord : PDWord;
  pRegString : PChar;
  pRegQWord : PInt64;
  i         : DWord;

begin
  Result := '';
  case p_dwRegDataType of
    REG_BINARY,
    REG_MULTI_SZ,
    REG_NONE,
    REG_LINK,
    REG_RESOURCE_LIST,
    REG_FULL_RESOURCE_DESCRIPTOR,
    REG_RESOURCE_REQUIREMENTS_LIST :
      begin
        pRegBinary := p_pValueData;
        for i := 1 to p_dwDataLen do
        begin
          Result := Result + IntToHex(pRegBinary^,2)+#32;
          inc(pRegBinary);
        end;
        Result := trim(Result);
      end;
    REG_DWORD :
      begin
        pRegDWord := p_pValueData;
        Result   := IntToHex(pRegDWord^,8) + ' ('+IntToStr(pRegDWord^)+'/'+IntToStr(integer(pRegDWord^))+')';
      end;
    REG_DWORD_BIG_ENDIAN :
      begin
        pRegBinary := p_pValueData;
        for i := 1 to 4 do
        begin
          Result := Result + IntToHex(pRegBinary^,2);
          inc(pRegBinary);
        end;
      end;
    REG_EXPAND_SZ,
    REG_SZ :
      begin
        pRegString := p_pValueData;
        Result    := pRegString;
      end;
    REG_QWORD :
      begin
        pRegQWord := p_pValueData;
        Result   := IntToHex(pRegQWord^,16) + ' ('+IntToStr(pRegQWord^)+')';
      end;
  end;
end;
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#8
  Alt 10. Jun 2002, 17:22
Danke bisher für deine Geduld, aber es ist noch nicht vorbei...

Folgender Schnipsel ist für mich relevant:
Zitat:
Code:
REG_SZ :
      begin
        pRegString := p_pValueData;
        Result       := pRegString;
      end;
Wenn der Reg-Eintrag also ein String ist, wird einer PChar-Variablen der Wert des Pointers zugewiesen. Einem String wird anschließend der Wert der PChar-Variable zugewiesen. Leider funktioniert das bei mir nicht. Der String ist leer.

Also bei folgendem Code bekomme ich eine leere Box:
Code:
  RegQueryValueEx(RegHnd, PChar('IsAlive'), nil, @dwValueType, pBuffer, @dwBufferLen);
  ShowMessage(RegDatatoString(dwValueType, pBuffer, dwBufferLen));
Der Typ und die Länge stimmen aber. Was hab ich falsch gemacht?

P.S.: Wie es schon in der Sesamstraße heißt: Wer nicht fragt, bleibt dumm.
Martin Leim
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#9
  Alt 10. Jun 2002, 17:45
Moin Chewie,

das kann ich mir nur so erklären, dass Du vergessen hast, den Buffer zu initialisieren, also z.B. pBuffer := AllocMem(100).
Wenn der auf nil steht, dürftest Du das beschriebene Ergebnis erhalten.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#10
  Alt 10. Jun 2002, 18:11
Das hatte ich wirklich nicht gemacht, aber auch so geht es nicht. Ich probier mal noch ein paar andere Wege aus, vielleicht finde ich dann Näheres über meinen Fehler.
Martin Leim
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz