Entwickler-Ecke
Dateizugriff - Exception bei holen von Reg-werten
Cruiser23 - Do 13.11.03 17:00
Titel: Exception bei holen von Reg-werten
Habe ein kleines Prob:
Wenn ich folgenden Code ausführe... :
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.FormCreate(Sender: TObject); begin with TRegistry.Create do begin try Rootkey:= HKEY_LOCAL_MACHINE; OpenKey('SYSTEM\ControlSet001\Control\',False); WaitToKillSpEdt.Value:= ReadInteger('WaitToKillServiceTimeout'); finally Free; end; end; end; |
...sagt mir Delphi das eine Exception auftritt, und zwar beim holen der Werte.
JEMAND NE AHNUNG WARUM?
Delete - Do 13.11.03 17:06
Hast du Adminrechte? Gibt es den Schlüssel? Klappt das öffnen? (OpenKey hat einen Rückgabewert, wie wäre es mit Testen?) Gibt es den Wert? ...
Terra23 - Do 13.11.03 17:09
... dafür gibt's anstelle von Try..Finally..End das Try..Except..End, aber das ist hier wohl nicht notwendig. Dein Code ist in meinen Augen falsch.
Statt
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.FormCreate(Sender: TObject); begin with TRegistry.Create do begin try Rootkey:= HKEY_LOCAL_MACHINE; OpenKey('SYSTEM\ControlSet001\Control\',False); WaitToKillSpEdt.Value:= ReadInteger('WaitToKillServiceTimeout'); finally Free; end; end; end; |
muss es so heißen:
Delphi-Quelltext
1: 2:
| Datei:=TRegistry.Create; With TRegistry Do ........ |
Datei ist eine Variable vom Typ TRegistry und wenn du schreibst,
Delphi-Quelltext
1: 2: 3: 4:
| With TRegistry.Create Do ..... RootKey... OpenKey... |
enstpricht das nichts anderem als
Delphi-Quelltext
1: 2:
| TRegistry.Create.RootKey... TRegistry.Create.OpenKey... |
und das löst die Exception aus, weil du die Create-Anweisung nur einmalig aufrufen darfst/solltest und dann nur noch mit TRegistry. arbeitest. Verstanden? ;-)
Anonymous - Do 13.11.03 17:12
Nein, TRegistry.Create gibt ein TRegistry-Objekt zurück, das dann benutzt wird. Daher muss auch der finally-Teil da sein, damit das Objekt wieder freigegeben werden kann.
Cruiser23 - Do 13.11.03 17:18
| Luckie hat folgendes geschrieben: |
| Hast du Adminrechte? Gibt es den Schlüssel? Klappt das öffnen? (OpenKey hat einen Rückgabewert, wie wäre es mit Testen?) Gibt es den Wert? ... |
Habe die Rechte (weiß ich dank deiner Antwort).
Den Schlüssel gibt es bei XP.
Der Wert ist (wenn man nicht daran rumgespielt hat = 20000)
Is die Zeit die Windows XP beim runterfahren hat um Services zwangsweise zu beenden!
| Terra23 hat folgendes geschrieben: |
| Dein Code ist in meinen Augen falsch. |
Der Code is ausm EDH und funtzt sonst...
Delete - Do 13.11.03 17:35
@Terra23:
Delphi-Quelltext
1: 2:
| Datei:=TRegistry.Create; With TRegistry Do ........ |
Das ist auch falsch. Wenn schon dann bitte
BTW: Warum heißt die Variable eigentlich "Datei"? Wollen wir es dritten Personen möglichst schwer machen von dem Variablennamen auf den Datentyp / das Objekt zu schließen? :roll:
Cruiser23 - Do 13.11.03 17:40
Wenn es den Wert also gibt und der Aufruf stimmt,
woher kommt dann die Exception?
Delete - Do 13.11.03 17:43
Was liefert den OpenKey zurück?
Cruiser23 - Do 13.11.03 17:54
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| with TRegistry.Create do begin try Rootkey:= HKEY_LOCAL_MACHINE; if OpenKey('SYSTEM\ControlSet001\Control\',False) = True then ShowMessage('True'); WaitToKillSpEdt.Value:= ReadInteger('WaitToKillServiceTimeout'); finally Free; end; end; |
Liefert True zurück!
Terra23 - Do 13.11.03 18:29
@Luckie: Du hast Recht; mein Fehler. Mein Problem ist halt nur folgendes:
Wenn man With TRegistry.Create Do schreibt, dann habe ich gelernt, dass das nichts anderes bedeutet als sich stets das TRegistry.Create zu sparen. Das ist doch soweit richtig, oder?
Anonymous - Do 13.11.03 18:33
| obbschtkuche hat folgendes geschrieben: |
| TRegistry.Create gibt ein TRegistry-Objekt zurück, das dann benutzt wird. |
Erst lesen ;)
Da Create der Constructor ist, wird mit einem neuen TRegistry-Objekt weitergemacht.
Terra23 - Do 13.11.03 18:53
:oops: Hab's überlesen. Also hier mal das, was ich meine:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| Datei:=TRegistry.Create; Try Datei.RootKey:=...; Datei.OpenKey(...); Finally Datei.Free; End; |
So sieht der Code doch normalerweise aus. Wenn ich jetzt aber schreibe:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| With TRegistry.Create Do Begin Try RootKey:=...; OpenKey(...); Finally Free; End; End; |
dann bedeutet das doch (für mich jedenfalls) ausgeschrieben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| Try <span style="font-weight: bold">TRegistry.Create.</span>RootKey:=...; <span style="font-weight: bold">TRegistry.Create.</span>OpenKey(...); Finally <span style="font-weight: bold">TRegistry.Create.</span>Free; End; |
Versteht ihr, was ich meine? Ich kann mich ja auch irren, aber mir wurde halt beigebracht, dass die Anweisungen, die hinter dem
With stehen einfach das Schreiben einfacher machen sollen und diese Anweisungen hinter
With einfach stets vor die folgenden Anweisungen gehängt werden. Nun ja. Wie dem auch sei, das scheint ja offensichtlich nicht das Problem zu sein.
@Luckie: Schwer machen will ich es niemandem. Ich schrieb doch:
| Ich selbst hat folgendes geschrieben: |
Datei ist eine Variable vom Typ TRegistry...
|
Ich hätte sie ja auch dem Verständnis halber anders nennen können.. ;-)
Delete - Fr 14.11.03 09:31
| Terra23 hat folgendes geschrieben: |
wenn ich jetzt aber schreibe:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| With TRegistry.Create Do Begin Try RootKey:=...; OpenKey(...); Finally Free; End; End; |
dann bedeutet das doch (für mich jedenfalls) ausgeschrieben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| Try <span style="font-weight: bold">TRegistry.Create.</span>RootKey:=...; <span style="font-weight: bold">TRegistry.Create.</span>OpenKey(...); Finally <span style="font-weight: bold">TRegistry.Create.</span>Free; End; | |
Nein, das bedeutet, dass du Fehler machst. Es heißt nur ein einziges Mal
Delphi-Quelltext
1:
| Datei := TRegistry.Create; |
Und dann greifst du nur auf die Methoden und Eigenschaften des erzeugten Registry-Objektes zu.
bedeutet also, dass du dir das
bei den Aufrufen von Registry-Funktionen sparen kannst. So würde mein Vorschlag zum Thema aussehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| reg := TRegistry.Create(KEY_READ); if(reg <> nil) then with reg do try RootKey := HKEY_LOCAL_MACHINE; if OpenKey('SYSTEM\ControlSet001\Control',false) then try if ValueExists('WaitToKillServiceTimeout') then WaitToKillSpEdt.Value := ReadInteger('WaitToKillSeriveTimeout'); finally CloseKey; finally Free; end; |
Cruiser23 - Fr 14.11.03 13:22
@MathiasSimmack
Wenn ich deinen Code benutze, tritt die Exception auch auf. Ausserdem fehlte bei dir n end. Trozdem Danke für deine Hilfe.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TMainFrm.LoadConfig; var reg: TRegistry; begin reg := TRegistry.Create(KEY_READ); if(reg <> nil) then with reg do try RootKey := HKEY_LOCAL_MACHINE; if OpenKey('SYSTEM\ControlSet001\Control',false) then try if ValueExists('WaitToKillServiceTimeout') then WaitToKillSpEdt.Value := ReadInteger('WaitToKillSeriveTimeout'); finally CloseKey; end; finally Free; end; end; |
Hat sonst noch jemand eine Idee? Bin für jeden Vorschlag zu haben!
Delete - Fr 14.11.03 14:19
| Cruiser23 hat folgendes geschrieben: |
| Ausserdem fehlte bei dir n end. |
Stimmt, :oops: Wird hiermit nachgereicht:
Außerdem ist mir ein Tippfehler unterlaufen. Wenn du meinen Code 1:1 übernommen hast, dann prüfst du zwar ob die Variable "WaitToKillServiceTimeout" existiert, aber ausgelesen wird dann "WaitToKillSer
iveTimeout".
Delete - Fr 14.11.03 14:25
Ich habe den Fehler. "WaitToKillServiceTimeout" ist ein - *trommelwirbel* - String. Bin eben mal ins XP gewechselt und habe nachgeschaut. Soll heißen: "ReadInteger" kann nichts werden.
Du, @Cruiser, musst den String auslesen und am besten mit "StrToIntDef" in einen Integer konvertieren. "StrToIntDef" deshalb, weil du hier einen Defaultwert angeben kannst, der im Fehlerfall benutzt wird.
Cruiser23 - Fr 14.11.03 14:27
Selbst wenn ich es wieder in Service ändere, tuts das nich!
Hast du ne Idee, worans liegen könnte?
//Edit:
:oops: Wenn ich StrToInt benutze tuts das doch! Wofür steht das "Def" in "StrToIntDef"? Werde mal in die Delphi-Hilfe schauen...
Delete - Fr 14.11.03 14:40
Ich empfehle "StrToIntDef", weil du damit a) den Defaultwert hast und b) einen
try/
except-Block sparst. Probier´s mit dem folgenden
gewollt falschen! Beispiel aus:
Delphi-Quelltext
1:
| WaitToKillSpEdt.Value := StrToIntDef('a',0); |
vs.
Delphi-Quelltext
1:
| WaitToKillSpEdt.Value := StrToInt('a'); |
Um den Fehler im zweiten Aufruf abzufangen, müsstest du (wie schon erwähnt)
try und
except nutzen. Und genau deshalb nehme ich in solchen Fällen "StrToIntDef".
Die Registry-Unit bietet übrigens mit "GetDataType" noch eine Funktion an, mit der man den Typ prüfen kann. Sprich: bevor du die Daten lädtst, kannst du testen ob es denn überhaupt ein String (oder was immer du vielleicht auslesen willst) ist.
Cruiser23 - Fr 14.11.03 16:45
Werd ich mir merken, Danke. Is ne praktische Sache das!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!