![]() |
Kapseln von Registryzugriffen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe eine Programm geschrieben, in dem häufig auf die Registry zugegriffen wird. Leider muss ich das irgendwann eines Tages auch mal warten. Und da die Werte (Schlüsseleinträge) immer mehr wurden und noch werden, dachte ich mir das ganze in ein Object zu kapseln. So könnte ich dann sehr komfortabel einfach auf die Eigenschaften dieses Objects zugreifen und müsste nicht immer umständlich mit TRegistry arbeiten. Den allerersten Anfang habe ich gemacht. Nur leider funktioniert das Schreiben des Wertes nicht. Denn Quellcode habe ich mal angefügt. Kann mir jemand sagen, warum es nicht geht und wie ich es hinbekomme? Gruß und Dank, Alex |
Re: Kapseln von Registryzugriffen
Bitte poste doch den relevanten Quellcode. Ich denke, die wenigsten haben Lust erst ein Archiv runterzuladen, es zu entpacken und dann noch einen Editor zum Betrachten deines Quellcodes zu öffnen.
|
Re: Kapseln von Registryzugriffen
Hallo,
ausgehend vom Quelltext ist für mich nicht erkennbar, warum das Schreiben nicht funktionieren sollte. |
Re: Kapseln von Registryzugriffen
Zitat:
Delphi-Quellcode:
für jede einzelne Abfrage der Registry vermeiden. Es kommt hinzu, dass ich häufig zwischen den RootKeys HKEY_CURRENT_USER und HKEY_LOCAL_MACHINE wechseln muss. Es soll daher mindestens das Anlegen von RINI und das Freigeben nicht jedesmal gemacht werden müssen.
Function Holewert: String;
Var RINI : TRegistry; Begin Result:=''; RINI:=TRegistry.Create; Try RINI.RootKey:=HKEY_CURRENT_USER; If RINI.OpenKeyReadOnly('Irgendwas') Then Begin Result:=RINI.ReadString('Irgendwas'); RINI.CloseKey; End; Finally RINI.Free; End; End; Zitat:
Delphi-Quellcode:
Unit AdvoPlex_Object;
Interface Uses Windows, Classes, Registry; Const {$EXTERNALSYM HKEY_CURRENT_USER} HKEY_CURRENT_USER = ($80000001); {$EXTERNALSYM HKEY_LOCAL_MACHINE} HKEY_LOCAL_MACHINE= ($80000002); AdvoPfad ='Software\AdvoSolutions\AdvoPlex'; Type TAdvoPlex = Class(TComponent) Private RINI : TRegistry; FUserSU : String; Protected Function GetUser: String; Function GetUserSU: String; Procedure SetUserSU(Value: String); Public Constructor Create(AOwner:Tcomponent);Override; Destructor Destroy; Override; Published Property User : String Read GetUser; Property UserSU : String Read GetUserSU Write SetUserSU; End; Implementation Constructor TAdvoPlex.Create(AOwner: TComponent); Begin Inherited Create(AOwner); RINI:=TRegistry.Create; End; Destructor TAdvoPlex.Destroy; Begin RINI.Free; Inherited Destroy; End; Function TAdvoPlex.GetUser; Function WhoAmI: String; Var Buffer : Array [0..MAX_PATH] Of Char; Size : DWORD; Begin Size:=SizeOf(Buffer); GetUserName(Buffer,Size); SetString(Result,Buffer,lstrlen(Buffer)); End; Begin Result:=WhoAmI; End; Function TAdvoPlex.GetUserSU; Begin RINI.RootKey:=HKEY_CURRENT_USER; If RINI.OpenKeyReadOnly(AdvoPfad) Then Begin Result:=RINI.ReadString('User'); RINI.CloseKey; End; End; Procedure TAdvoPlex.SetUserSU(Value: string); Begin RINI.RootKey:=HKEY_CURRENT_USER; If RINI.OpenKey(AdvoPfad, True) Then Begin RINI.WriteString('User', Value); RINI.CloseKey; End; End; End. Zitat:
Gruß, Alex |
Re: Kapseln von Registryzugriffen
Zitat:
Ich verstehe es ja auch nicht :wall: Ich bekomme immer die Meldung: "Im Projekt ist eine Exception der Klasse ERegistryException mit der Meldung 'Fehler beim Setzen der Daten für 'User'' aufgetreten. Achso: Ich habe TurboDelphi 2006. Gruß, Alex |
Re: Kapseln von Registryzugriffen
Das was du als Datei angehangen hast, ist auch nicht mher, als das was du jetzt gepostet hast. Warum sollte man den Fehler also besser finden?
Hast du deinen Code schon mal debuggt? Wie benutzt du die Klasse? |
Re: Kapseln von Registryzugriffen
Hallo @Schwedenbitter,
mit Deinem unveränderten Quelltext (D7 Prof.) tritt der Fehler nicht auf. Der Eintrag wird in die Registrierung geschrieben. |
Re: Kapseln von Registryzugriffen
Zitat:
@nahpets Könntest Du mir bitte mal einen Gefallen tun? Ich gehe davon aus, dass D7 Prof beim Öffnen und/oder Schließen eine .cfg-Datei schreibt. Ich vermute anhand des Erfolges bei Dir, dass es evtl. an irgend welchen Compiler-Einstellungen liegen könnte. Kann ich bitte mal die .cfg-Datei (ggf. auch als PM) bekommen, mit der Du das kompiliert hast? Ich suche insofern auch mal BETA-Tester :lol:, denen ich das mal als exe zukommen lassen könnte, um auszuschließen, dass es an meinem/meinen System(en) liegt. Ich weiß nicht, ob die Forenregeln das Anhängen von exe-Dateien zulassen und bin zu beschäftigt, um das auf die Schnelle nachzusehen. Gruß, Alex |
Re: Kapseln von Registryzugriffen
Also Du könntest Dir einiges an Code sparen, wenn Du eine globale Variable von Typ TRegistry nutzt, die Du beim Programmstart initialisierst und beim Programmende wieder auflöst. So mache ich das zumindest in meinen Projekten. Alternativ könntest Du auch die JclRegistry Unit aus den Jedis nutzen ;)
|
Re: Kapseln von Registryzugriffen
Hallo,
anliegend das ganze Projekt mit Exe zum Probieren. |
Re: Kapseln von Registryzugriffen
Keine Ahnung woran es gelegen hat. Aber das Konzept war sowieso nicht schön. Hier mal meine Version:
Delphi-Quellcode:
Und die Verwendung:
unit AdvoPlex_Object;
interface uses Windows, Classes, SysUtils, Registry; const ADVOPATH = 'Software\AdvoSolutions\AdvoPlex'; type TAdvoPlex = class(TObject) private FUserSU: string; function CurrentUser: string; function GetUserSU: string; procedure SetUserSU(Value: string); public constructor Create; destructor Destroy; override; published property UserSU: string read GetUserSu write SetUserSU; procedure SaveUserSU; procedure LoadUserSU; end; implementation constructor TAdvoPlex.Create; begin inherited Create; end; destructor TAdvoPlex.Destroy; begin inherited Destroy; end; function TAdvoPlex.GetUserSU: string; begin Result := FUserSU; end; procedure TAdvoPlex.LoadUserSU; var reg: TRegistry; begin reg := TRegistry.Create(KEY_READ); try reg.RootKey := HKEY_CURRENT_USER; if reg.OpenKeyReadOnly(ADVOPATH) then begin FUserSU := reg.ReadString('User'); reg.CloseKey; end else raise Exception.CreateFmt('%s'+#13#10+'%s', ['Fehler beim Lesen von UserSU', SysErrorMessage(GetLastError)]); finally reg.Free; end; end; procedure TAdvoPlex.SaveUserSU; var reg: TRegistry; begin reg := TRegistry.Create(KEY_ALL_ACCESS); try reg.RootKey := HKEY_CURRENT_USER; if reg.OpenKey(ADVOPATH, True) then begin reg.WriteString('User', FUserSU); reg.CloseKey; end else raise Exception.CreateFmt('%s'+#13#10+'%s', ['Fehler beim Schreiben von UserSU', SysErrorMessage(GetLastError)]); finally reg.Free; end; end; procedure TAdvoPlex.SetUserSU(Value: string); begin FUserSU := Value; end; function TAdvoPlex.CurrentUser: string; var Buffer : array[0..MAX_PATH] of Char; Size : DWORD; begin Size := SizeOf(Buffer); GetUserName(Buffer, Size); SetString(Result, Buffer, lstrlen(Buffer)); end; end.
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin AdvoPlex := TAdvoPlex.Create; try try AdvoPlex.LoadUserSU; ShowMessage(AdvoPlex.UserSu); AdvoPlex.UserSU := 'Test01'; AdvoPlex.SaveUserSU; except on E: Exception do ShowMessage(e.Message); end; finally AdvoPlex.Free; end; end; |
Re: Kapseln von Registryzugriffen
Ich würde das ganz so realisieren:
Delphi-Quellcode:
Dadurch ersparst Du Dir zumindest das ständige Anlegen und Löschen der Registry-Instanzen.
unit AdvoPlex_Object;
interface uses Windows, Classes, SysUtils, Registry; const ADVOPATH = 'Software\AdvoSolutions\AdvoPlex'; type TAdvoPlex = class(TObject) private FUserSU: string; function CurrentUser: string; function GetUserSU: string; procedure SetUserSU(Value: string); procedure SaveUserSU; procedure LoadUserSU; public constructor Create; destructor Destroy; override; published property UserSU: string read GetUserSu write SetUserSU; end; implementation constructor TAdvoPlex.Create; var reg: TRegistry; begin inherited Create; reg := TRegistry.Create(KEY_ALL_ACCESS); reg.RootKey := HKEY_CURRENT_USER; end; destructor TAdvoPlex.Destroy; begin FreeAndNil(reg); inherited Destroy; end; function TAdvoPlex.GetUserSU: string; begin LoadUserSU; Result := FUserSU; end; procedure TAdvoPlex.LoadUserSU; begin if reg.OpenKeyReadOnly(ADVOPATH) then begin FUserSU := reg.ReadString('User'); reg.CloseKey; end else raise Exception.CreateFmt('%s'+#13#10+'%s', ['Fehler beim Lesen von UserSU', SysErrorMessage(GetLastError)]); end; procedure TAdvoPlex.SaveUserSU; begin if reg.OpenKey(ADVOPATH, True) then begin reg.WriteString('User', FUserSU); reg.CloseKey; end else raise Exception.CreateFmt('%s'+#13#10+'%s', ['Fehler beim Schreiben von UserSU', SysErrorMessage(GetLastError)]); end; procedure TAdvoPlex.SetUserSU(Value: string); begin FUserSU := Value; SaveUserSU; end; function TAdvoPlex.CurrentUser: string; var Buffer : array[0..MAX_PATH] of Char; Size : DWORD; begin Size := SizeOf(Buffer); GetUserName(Buffer, Size); SetString(Result, Buffer, lstrlen(Buffer)); end; end. Edit: Warum rufst Du LoadUserSU und SaveUserSU von Hand und nicht in SetUserSU und GetUserSU auf? |
Re: Kapseln von Registryzugriffen
Zitat:
|
Re: Kapseln von Registryzugriffen
Zuerst mal Danke für die vielen Code-Vorschläge. Ich kann mich garnicht entscheiden, was ich nehmen soll :mrgreen:
Zitat:
Danke für die Mühen. Also wenn die exe bei Dir funktioniert - wovon ich ausgehe - dann liegt es an meinem System (XP Prof. SP3). Wenn ich die bei mir aufrufe, bekomme ich denselben Fehler. Und das gleich auf 2 Rechnern :gruebel: @HeikoAdams Das mit der globalen TRegistry-Variable hatte ich ja zuerste probiert. Ich wollte das in eine ganz stinknormale Unit packen. Aber da kamen auch die Fehler und da dachte ich mir, mache ich es richtig(er). Leider bislang ohne Erfolg. Zitat:
Was bedeutet "gelegen hat"? Kam der Fehler bei Dir auch? Gruß, Alex |
Re: Kapseln von Registryzugriffen
Zitat:
|
Re: Kapseln von Registryzugriffen
Hallo,
Zitat:
|
Re: Kapseln von Registryzugriffen
Zitat:
(1) Ich mache das, was man nicht tun sollte: Bin stets als Admin angemeldet. (2) Ich habe jetzt mangels Geduld angefangen, die Set-/Get-Procedures so zu schreiben, dass in jeder einzelnen TRegistry angelegt, bearbeitet etc. wird und es klappt. (3) Wenn es Rechteprobleme wären, sähe die Fehlermeldung anders aus. Ich danke trotzdem für Eure sehr ausführliche Hilfe. Gruß, Alex |
Re: Kapseln von Registryzugriffen
Ich bekam immer eine Exception beim Lesen aus der Registry. Deswegen habe ich aus dem globalen Registry Objekt ein lokales gemacht, dann ging es auf einmal. Das hat auch noch den Vorteil, dass die Registry auch nur lesend geöffnet wird, wenn ich auch nur lesen will. Bei Heiko ist die Registry jetzt die ganze Zeit über mit vollen Rechten geöffnet. Bei HKCU kein Problem, aber bei anderen Schlüsseln eventuell.
Und ich rufe SaveUserSU und LoadUserSU nicht im Getter und Setter auf, damit der Benutzer der Klasse entscheiden kann, wann geschrieben und wann gelesen werden soll. Desweiteren gehört so was in einen Getter und Setter nicht rein. Diese Methoden sind dazu da Attribute der Klasse zusetzen und auszulesen. Wenn ich einen Setter aufrufe, rechne ich nicht damit, dass der irgendwas in meinem System rumschreibt. Ich hatte also schon meine Gründe für meine Lösung. ;) |
Re: Kapseln von Registryzugriffen
Zitat:
Nur ist TAdvoPlex ausschließlich für mich. Es gibt 5 Programmmodule, die alle Ihre Daten aus der Registry von denselben Schlüsseln holen und dorthin schreiben. Bislang eine wahnsinns Durcheinander. Der Suffix bei z.B. UserSU kommt als Anlehung aus Linux (=SuperUser). Nur der Admin kann mit einem Setup-Programm in HKEY_LOCAL_MACHINE schreiben. Die anderen dürfen nur lesen. Sie sollen aber diese Werte geringfügig abändern und eben unter HKEY_CURRENT_USER abspeichern dürfen. Sie haben nur ein Mini-Setup, in dem aber die Werte beider Schlüssel verglichen werden. Dort gibt es auch für jeden Eintrag ein Button "Default", wobei Default die Werte von HKEY_LOCAL_MACHINE sind. Wenn ich nun z.B. nur bei User auf Default klicke, macht es daher - vielleicht auch nur bei mir - Sinn, es gleich in die Registry zu schreiben. Es macht mir sonst einfach zuviel Aufwand mit entsprechenden Variablen in den jeweiligen Programmmodulen auf Änderungen zu prüfen etc. pp. Ich hoffe, das versteht jemand einigermaßen :pale: Was ich damit nur sagen wollte: Somit hatte ich für meine Lösung auch Gründe :mrgreen: Es kommt hinzu, dass ich ja - meistens - weiß, was ich tue (in die Registry schreiben). Gruß, Alex |
Re: Kapseln von Registryzugriffen
Ich finde es einfach nur nicht sauber, wenn Routinen nicht das machen, wofür sie gedacht sind. Und ein Setter macht für mich nun mal nichts anderes als das zugehörige Attribut setzen.
Aber OK, ist deine Entscheidung. Allerdings sollte Faulheit nie dazu führen deswegen schlechten Code zu schreiben. |
Re: Kapseln von Registryzugriffen
Zitat:
Zitat:
Zum anderen ist "schlecher Code" auch eine Definitionsfrage. Ich habe es jetzt fertig und es tut genau das, was ich brauche. Leider habe ich nun 7 Zeilen pro Setter/Getter "zu viel", weil es - ob nun wegen des Compilers oder vermutlich eher wegen meiner Systeme - nicht klappt. Das waren dann 154 Zeilen, die ich mir eigentlich sparen wollte. Wäre dem nicht so gewesen, gäbe es diesen Thread nicht und niemand hätte gemerkt, dass ich faul bin :lol:. Danke an alle. Alex |
Re: Kapseln von Registryzugriffen
Zitat:
|
Re: Kapseln von Registryzugriffen
Zitat:
Vergesse ich nun, das SaveUserSU nach einer Änderung aufzurufen, dann suche ich mich irgendwann dumm und dämlich, weil ich nicht weiss, warum es nicht funktioniert. Das gäbe dann ein heilloses Durcheinander. Und da die Werte gleich geschrieben werden sollen, kann man das doch gleich mit erledigen. Das beschriebene System funktioniert seit ca. 4 Monaten sehr gut. Ich will nur in 10 Jahren den Code auch noch verstehen. Eventuell hast Du ja Recht. Dann werde ich mich, wenn es soweit ist, nochmal melden. Dein Code mag sicher sauber, richtig, was auch immer sein. In meinem konkreten Fall bin ich aber der Meinung, dass mein Vorgehen vielleicht nicht sauber, richtig etc. aber sinnvoller ist. Auch bin ich überzeugt, dass derjenige, der den Code "erbt", ohnehin das System verstehen muss. Tut er das, dann begreift er den Code ebenso ohne die m.E. nicht überflüssige Dokumentation. In einem muss ich Dir (wieder) uneingeschränkt Recht geben: Dein Code hat den Charme, dass er mir die mind. 154 Zeilen minus einer Procedure erspart hätte. Denn damit würde man in einem Rutsch alles in die Registry schreiben / aus ihr lesen. Das bedeutete dann aber auch Overhead, falls man nur einen einzigen Wert ändert. Gruß, Alex |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:37 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