![]() |
Daten aus der Registry lesen mit TService
Hallo,
ich versuche einen NT-Dienst zu schreiben, in dem ich prüfe ob ein bestimmter Rechner noch über einen Ping im Netzwerk zu erreichen ist. Dies funktioniert auch sehr gut. Der Dienst lässt sich starten und stoppen, nur wenn ich die gespeicherten Daten aus der Registry lesen will tut sich gar nichts. Er liest die Daten nicht. Wenn ich den Abschitt für das lesen der Registry deaktiviere, funktioniert die Routine, so wie jetzt wird der Timer nicht vollständig durchlaufen. Oder kann man im TService nicht in der Registry lesen. Wo habe ich da einen Denkfehler.
Delphi-Quellcode:
//------------------------------------------------------------------------------ // Arbeitsroutine procedure TService.Timer1Timer(Sender: TObject); var Regi: TRegistry; const FileName = 'c:\temp\pinglog.txt'; begin If RegRead=True then begin Regi := TRegistry.Create; try Regi.RootKey := HKEY_LOCAL_MACHINE; if Regi.OpenKey('SOFTWARE\JF\AutoDown', True) then begin MIP:=regist.ReadString('IP'); MZeit:=regist.ReadString('Zeit'); end finally regist.Free; end; if MIP = '' then begin MIP := '127.0.0.1'; MZeit := '30'; end; // ReceiveTimeout einstellen ICMP_Service.ReceiveTimeout := 1000; // Zähler für Shutdown auf null setzen; MZaehler:=0; RegRead:=False; end; AssignFile(f,FileName); if FileExists(FileName) then Append(f) else Rewrite(f); // Ping starten ICMP_Service.Host := MIP; // Ping senden ICMP_Service.Ping; if ICMP_Service.ReplyStatus.FromIpAddress = '0.0.0.0' then begin if MZaehler <= strtoint(MZeit) then begin MZaehler:=MZaehler+1; IF MZaehler < strtoint(MZeit) then writeln(f,inttostr(Mzaehler)+' Ping an IP ' +MIP + ' nicht i.o. ' + datetimetostr(now())) else begin writeln(f,'Shutdown wird eingeleitet '+ inttostr(Mzaehler)+' Ping an IP ' +MIP + ' nicht i.o. ' + datetimetostr(now())); CloseFile(f); // ExWindows(EWX_Poweroff); //Herunterfahren und Ausschalten end; end; end else begin // Zähler für Shutdown auf 0 setzen; MZaehler:=0; writeln(f,'Ping an IP ' +ICMP_Service.ReplyStatus.FromIpAddress + ' ok.'); end; CloseFile(f); end; |
Re: Daten aus der Registry lesen mit TService
Ich frage mich, ob man in einem Service überhaupt einen Timer benutzen kann, denn an welches Fenster soll er denn seine WM_TIMER Nachricht schicken? Versuch doch mal, nur zum Testen ausserhalb der Timer-Prozedur auf die Registry zu zugreifen und schreib parallel eine Log-Datei, damit du siehst, wo der Service gerade ist.
|
Re: Daten aus der Registry lesen mit TService
ja ausserhalb des Timers funktioniert das lesen aus der Registry einwandfrei,
auch so funktioniert es.
Delphi-Quellcode:
if FileExists(FileName) then Append(f)
else Rewrite(f); writeln(f,'timerstart'); If RegRead=True then begin // Regi := TRegistry.Create; writeln(f,'create'); try writeln(f,'try'); // Regi.RootKey := HKEY_LOCAL_MACHINE; // if Regi.OpenKey('SOFTWARE\JF\AutoDown', True) then // begin // writeln(f,'lese'); // MIP:=regist.ReadString('IP'); // MZeit:=regist.ReadString('Zeit'); // end finally writeln(f,'finally'); // regist.Free; end; |
Re: Daten aus der Registry lesen mit TService
Hallo Luckie,
ich habe hier im Forum gelesen, das man einen Timer im tService benutzen kann, aber nicht muss, aber wo soll ich denn dann aus der Registry lesen? ich habe den Fehler jetzt so weit eingegenzt, dass ich weiss das es an
Delphi-Quellcode:
nur verstehen tue ich das nicht da die Werte ja in der Registry stehen :gruebel:
MIP := regist.ReadString('IP');
MZeit:= regist.ReadString('Zeit'); Gruss Jörg |
Re: Daten aus der Registry lesen mit TService
Delphi-Quellcode:
Du initialisiert "Regi", benutzt später aber "regist".
var
Regi: TRegistry; ... Regi := TRegistry.Create; try Regi.RootKey := HKEY_LOCAL_MACHINE; if Regi.OpenKey('SOFTWARE\JF\AutoDown', True) then begin MIP:=regist.ReadString('IP'); MZeit:=regist.ReadString('Zeit'); end finally regist.Free; Gruß Igotcha |
Re: Daten aus der Registry lesen mit TService
Vielen Dank Igotcha,
manchmal sieht man den Wald vor Bäumen nicht. jetzt funktioniert es auch, warum sollte es auch nicht :lol: |
Re: Daten aus der Registry lesen mit TService
Hallo,
ich habe es mit den o.g. Tips ausprobiert, aber bislang keinen Erfolg gehabt. Zur Vereinfachung und auch für mein Verständnis habe ich mir jetzt einen Dienst geschrieben, der nur einen Registry-Wert (ist vorhanden) ausliest und in einer Log-Datei das Ergebnis vermerkt und sonst nichts weiter macht. Die einzige Procedure die ich hinzugefügt habe, ist die für das Ereignis OnStart. Ich habe denselben Code in einer Anwendung gehabt. Dort hat das alles prima geklappt. Nach dem Portieren in den Dienst geht das mit dem Auslesen der Registry nicht mehr.
Delphi-Quellcode:
Wo liegt mein Fehler? Bin völlig ratlos!
Procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
Var Reg : TRegistry; Quelle : String; F : Text; Begin Reg:=TRegistry.Create; Try Reg.RootKey:=HKEY_CURRENT_USER; If Reg.OpenKeyReadOnly('Software\Olympus\DSSPlayer2002\Dictation Module\DownLoad\InstallSetting') Then Quelle:=Reg.ReadString('DictationPath')+'\' Else Quelle:='Error'; Finally Reg.Free; End; AssignFile(F,'Test.log'); {$I-} ReWrite(F); WriteLn(F,Quelle); CloseFile(F); {$I+} End; |
Re: Daten aus der Registry lesen mit TService
@Schwedenbitter: Ich gehe davon aus, dass Du Deinem Service keinen User zugewiesen hast. Dadurch wird als User System verwendet. Dieser User ist nicht in der Lage, Deinen User-Bereich auszulesen.
Deine Abfrage sollte funktionieren, wenn Du dem Service Deinen Useraccount zuweist. Gruß Thomas |
Re: Daten aus der Registry lesen mit TService
Zitat:
Es ist sogar noch besser. Als Teil der TCB hat man sogar Backup/Restore-Rechte und kann damit Registry-Hives mounten. Damit kann man also die NTUSER.DAT eines beliebigen Benutzers einbinden. Aber gehen wir mal davon aus, daß der Benutzer dessen Registrywerte den Service interessieren im Moment eingeloggt ist und damit sein Profil (NTUSER.DAT) geladen ist. In diesem Fall hole man sich die SID des Benutzers (notfalls auch den vollen Namen) und lese den entsprechenden Wert unter HKEY_USERS aus. Beispiel. Insofern "Administrator" gerade eingeloggt ist und es sich um das eingebauten Adminkonto handelt, wird der Schlüssel HKEY_USERS\S-1-5-21-??????????-??????????-??????????-500 das gleiche enthalten wie HKEY_CURRENT_USER im Kontext dieses Benutzers. Probiert es einfach aus. Zitat:
Zitat:
|
Re: Daten aus der Registry lesen mit TService
Zitat:
P.S. Ich verstehe auch nicht ganz, warum ich das mit meiner Anwendung prima auslesen kann. Sofern das SYSTEM quasi als User benutzt wird, wäre doch davon auszugehen, dass dieses ziemlich viel Rechte hat und die Werte deshalb lesen kann ... |
Re: Daten aus der Registry lesen mit TService
Zitat:
Zitat:
|
Re: Daten aus der Registry lesen mit TService
Zitat:
|
Re: Daten aus der Registry lesen mit TService
Ich zitiere mich mal selber:
Zitat:
|
Re: Daten aus der Registry lesen mit TService
So, ich habe mir im Netz jetzt folgenden Quellcode zusammengesucht bzw. gebastelt:
Delphi-Quellcode:
In meiner Anwendung funktioniert das und ich bekomme die lange Nummer. Wenn ich das in meinen Dienst einbaue, erhalte ich als Ergebnis immer S-1-5-18. Liegt vermutlich daran, dass der Dients als Benutzer System hat.
Function GetSID:String;
Function TokenToUserSidString(Token:THandle):String; Const SECURITY_NT_AUTHORITY = 5; Type PSID = ^TSID; TSID = Packed Record Revision : Byte; SubAuthorityCount : Byte; IdentifierAuthority : TSIDIdentifierAuthority; // [0..SubAuthorityCount - 1] SubAuthority : Array [Byte] Of DWORD; End; PTokenUser = ^TTokenUser; TTokenUser = Record User : TSIDAndAttributes; End; Var User : PTokenUser; Size : DWORD; Loop : Byte; Begin Result:=''; Size:=4096; GetMem(User,Size); Try FillChar(User^,Size,0); If GetTokenInformation(Token,TokenUser,User,Size,Size) Then With PSID(User^.User.Sid)^ Do Begin Result:='S-'+IntToStr(Revision)+'-'+ IntToStr(IdentifierAuthority.Value[SECURITY_NT_AUTHORITY]); For Loop:=0 To SubAuthorityCount-1 Do Result:=Result+'-'+IntToStr(SubAuthority[Loop]); End; Finally FreeMem(User); End; End; Var Token : THandle; Begin If OpenProcessToken(GetCurrentProcess,TOKEN_QUERY,Token) Then Begin Try Result:=TokenToUserSidString(Token); Finally CloseHandle(Token); End; End Else Result:='Error'; End; Wie kann ich das ändern? |
Re: Daten aus der Registry lesen mit TService
Bequemer geht's mit
![]() Zitat:
![]() |
Re: Daten aus der Registry lesen mit TService
Danke!
Jetzt habe ich nur noch ein Problem: Welche der vielen Units, die sich in Remkos ![]() |
Re: Daten aus der Registry lesen mit TService
Guck doch einfach nach. :roll:
|
Re: Daten aus der Registry lesen mit TService
Schonmal was von GREP gehoert? Ich persoenlich kann PowerGREP3 empfehlen - benutze es fast jeden Tag. Die perfekte Loesung fuer grosse Quelltextverzeichnisse usw.
Vermutlich ist es JwaNtSecApi - aber wie gesagt, am einfachsten ist wenn du dich auf ![]() |
Re: Daten aus der Registry lesen mit TService
@Olli: Danke für die Hilfe.
Ich habe die Pakete jetzt geladen und das Verzeichnis meines Projektes kopiert. Außerdem habe ich den Teil des Quellcodes von Remko unter meinem o.g. Link kopiert, der die Uses-Anweisungen enthält. Während des Kompilierens bekomme ich die Fehlermeldung, dass JwaWinSta.dcu nicht gefunden wurde. Eine entsprechende Datei (JwaWinSta.pas) habe ich in den Paketen auch nicht finden können. Scheinbar kommt es aber genau auf diese an. Denn wenn ich JwaWinSta aus den zu verwendenden Units entferne, bekomme ich die Fehlermeldung Undefinierter Bezeichner 'SidToStr'. Ich habe auch Remkos Beispielprogramm runtergeladen und getestet. Abgesehen davon, dass bei mir die letzte Zahl nicht stimmt, statt der angezeigten 500 steht wie im Registrierungseditor 1003, lässt sich das Programm auch wegen der fehlenden JwaWinSta nicht kompilieren. Jetzt bin ich völlig verwirrt. |
Re: Daten aus der Registry lesen mit TService
Ich habe mir jetzt die Function SidToStr selbst zusammengebastelt, nachdem ich sie nirgends finden so oder in einer Unit konnte. Für den Fall, dass jemand Interesse hat:
Delphi-Quellcode:
Allerdings stehe ich vor demselben Problem wie das Programm LSALogon von Remko. Die letzten drei bzw. vier Ziffern des SID stimmen nicht. Damit komme ich nicht in diesen Unterschlüssel rein.
Function SIDToStr(SID:Windows.PSID):WideString;
Var SIA : PSIDIdentifierAuthority; dwCount : Cardinal; I : Integer; Begin If Not isValidSID(SID) Then Result:='Error' Else Begin Result:='S-'+IntToStr(Byte(SID^))+'-'; SIA:=GetSIDIdentifierAuthority(SID); Result:=Result+IntToStr(SIA.Value[5]); dwCount:=GetSIDSubAuthorityCount(SID)^; For I:=0 To (dwCount-1) Do Result:=Result+'-'+IntToStr(GetSIDSubAuthority(SID,I)^); End; End; Ich habe jetzt auf mehreren Rechnern festgestellt, dass es neben der 1003 auch noch mehrere Möglichkeiten gibt. Meine Idee, die 500 einfach durch eine 1003 zu ersetzen, geht damit leider auch nicht mehr. Schade eigentlich. |
Re: Daten aus der Registry lesen mit TService
Zitat:
![]() Einfach selber deklarieren, sollte nicht so schwer sein. |
Re: Daten aus der Registry lesen mit TService
Nach wie vor ist ConvertSidToStringSid eine Option, denke ich.
Zitat:
Ausserdem sagte ich bereits, dass der Benutzer bereits eingeloggt sein muss, fuer welchen du das erreichen willst. Ansonsten hast du keine Chance auf den (logischerweise) nicht-existenten Schluessel zuzugreifen. |
Re: Daten aus der Registry lesen mit TService
Delphi-Quellcode:
function ConvertSidToStringSidW(Sid: PSID; var StringSid: PWideChar): BOOL; stdcall; external 'Advapi32.dll';
function SIDToStr(SID: PSID): WideString; var lpcsSid: PWideChar; begin Result := 'Error'; if(ConvertSidToStringSidW(SID, lpcsSid)) try Result := WideString(lpcsSid); finally LocalFree(lpcsSid); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:21 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