|
Registriert seit: 19. Mai 2006 17 Beiträge |
#1
Hallo,
Ich habe da mal wieder eine Frage für die Cracks unter euch. Ich habe einen bestimmten Thread, der probiert via Service Control Manager (SCM) Verbindung einen Service auf einem anderen (oder auch den eignen, was dann trivial wäre) zu restarten. Mein Problem ist dabei, dass der Process, dem dieser Thread gehört, selbst ein Service ist, der selbst verständlich mit den Rechten des Benutzers "System" läuft. "System" hat aber keine Rechte auf den SCM eines entfernten Computers. Daher bestehen zwei Möglichkeiten. Der Thread der die Verbindung aufbaut muß mit anderen Rechten (unter einem anderen Benutzer) laufen oder die SCM Verbindung kann unter einen anderen Benutzernamen hergestellt werden. Nur weiß ich weder wie man das eine, noch wie man das andere macht.
Delphi-Quellcode:
Den bisher bestehend den Code des Threads habe ich hier mal hineingestellt. Dieser Thread soll einmal Teil eins Guardian Service sein.
{$REGION 'TimeOutHandler Thread'}
procedure TTimeOutHandler.setTimeOutMessage(Value : TTimeOutMessage); var i : Integer; begin FTimeOutMsg.ApplId:=Value.ApplId; FTimeOutMsg.ApplExe:=Value.ApplExe; FTimeOutMsg.ApplService:=Value.ApplService; FTimeOutMsg.ApplIP:=Value.ApplIP; FTimeOutMsg.ThreadId:=Value.ThreadId; FTimeOutMsg.CodePartId:=Value.CodePartId; FTimeOutMsg.StackCount:=Value.StackCount; setLength(FTimeOutMsg.Stack,Value.StackCount); for i := 0 to length(value.Stack) - 1 do FTimeOutMsg.Stack[i]:=Value.Stack[i]; FStep:= thsConnectService; end; procedure TTimeOutHandler.executeStateMachine; var schService, //Service Handle schSCManager:Integer; //Service Manager Handle; StackString, EmailText: TStringlist; ActionText, ListString:String; i : integer; function GuardianStopService: boolean; var ServiceState: SERVICE_STATUS; //Service State begin Result:=True; // Get the Services State Result:= QueryServiceStatus( schService, ServiceState); // is the Service allready stopped? if Result then if ServiceState.dwCurrentState > SERVICE_STOPPED then begin if ( ServiceState.dwCurrentState = SERVICE_STOP_PENDING ) then begin Sleep( ServiceState.dwWaitHint ); Result:= QueryServiceStatus( schService, ServiceState); if Result then Result := ServiceState.dwCurrentState = SERVICE_STOPPED; end else begin result:= ControlService( schService, SERVICE_CONTROL_STOP, ServiceState ); if ( ServiceState.dwCurrentState = SERVICE_STOP_PENDING ) then begin Sleep( ServiceState.dwWaitHint ); Result:= QueryServiceStatus( schService, ServiceState); if Result then Result := ServiceState.dwCurrentState = SERVICE_STOPPED; end; end; end; end; //function function GuardianStartService: boolean; var ServiceState: SERVICE_STATUS; //Service State CheckCount : Integer; Args : String; SvArgs : PAnsiChar; begin Args:=''; SvArgs:=PAnsiChar(Args); // Start the Service result:=StartService(schService,0,SvArgs); { // Get the Services State if Result then Result:= QueryServiceStatus( schService, ServiceState); // wait maximum 10s to get the Service in running state; CheckCount:=0; if Result then begin while ((ServiceState.dwCurrentState = SERVICE_START_PENDING) or (CheckCount<9) and result) do begin inc(CheckCount); sleep(1000); Result:= QueryServiceStatus( schService, ServiceState); end; if result then result :=ServiceState.dwCurrentState = SERVICE_RUNNING; end;} end; //function function GuardianOpenService(TimeOutMsg: TTimeOutMessage):Boolean; var Par1, Par2, Args : String; SvArgs : PAnsiChar; i: Integer; begin Args:=char(0); SvArgs:=PChar(Args); // Par1:=char(0); Par1:=TimeOutMsg.ApplIP+char(0); Par2:=TimeOutMsg.ApplService+char(0); Result:=True; //get Service Manager Handle: schSCManager := OpenSCManager(PChar(Par1),SERVICES_ACTIVE_DATABASE,SC_MANAGER_ALL_ACCESS); Result:= not(schSCManager = 0); //get Service Handle if Result then begin schService := OpenService(schSCManager,PChar(Par2), SERVICE_ALL_ACCESS); result:= not(schService = 0); end else i:=GetLastError; end; begin while not Terminated do begin case FStep of {$REGION 'thsConnectService'} thsConnectService: begin ActionText:='Tried: '; if not FTimeoutActions.RestartService then FStep:=thsKillExecutable else begin ActionText:=ActionText+'restart Service: '; if FTimeOutMsg.ApplService <> '' then begin if GuardianOpenService(FTimeOutMsg) then FStep:=thsStopService else begin FStep:=thsKillExecutable; ActionText:=ActionText+'couldn''t connect to Service Manager!'; end; end else begin ActionText:=ActionText+'Have no Service Name!'; FStep:=thsKillExecutable; end; end; end; {$ENDREGION} {$REGION 'thsStopService'} thsStopService: begin sleep(5000); if GuardianStopService then FStep:= thsStartService else begin ActionText:=ActionText+'Couldn''t stop the Service!'; FStep:=thsKillExecutable; End; end; {$ENDREGION} {$REGION 'thsStartService'} thsStartService: begin sleep(5000); if GuardianStartService then begin FStep:= thsSendMail; ActionText:=ActionText+'sucessfull'; end else begin ActionText:=ActionText+'Couldn''t start the Service!'; FStep:=thsKillExecutable; End; end; {$ENDREGION} {$REGION 'thsKillExecutable'} thsKillExecutable: Begin FStep:= thsSendMail; End; {$ENDREGION} {$REGION 'thsSendMail'} thsSendMail: if not FTimeoutActions.SendMail then FStep:=thsTerminateThread else begin EmailText:=TStringlist.Create; with EmailText do begin Delimiter:=#13; Clear; append('Application Timeout happens:'); append('============================'); append('Local Server Time: '+DateTimeToStr(now)); append('Application Computer IP: '+FTimeOutMsg.ApplIP); append('Application Executable Name: '+FTimeOutMsg.ApplExe); append('Application Service Name: '+FTimeOutMsg.ApplService); append('Application Internal Id: '+inttostr(FTimeOutMsg.ApplId)); if FTimeOutMsg.ThreadId>-1 then begin append('Application internal Thread Id: '+IntToStr(FTimeOutMsg.ThreadId)); if FTimeOutMsg.CodePartId>-1 then begin append('Application Thread Codepart Id: '+IntToStr(FTimeOutMsg.CodePartId)); append('The Codepart was not left of refreshed after the preset time interval'); append('Stack of entered codeparts:'); for i := 0 to FTimeOutMsg.StackCount - 1 do begin append('Level( '+IntToStr(i) +'):'+IntToStr(FTimeOutMsg.Stack[i])); end; end else begin append('The Applications Thread doesn''t send the its idle signal after the preset time interval'); end; end else append('The Application doesn''t send the application idle signal after the preset time interval'); append(ActionText); end; Form1.sendEmail(EmailText); EmailText.Free; FStep:= thsTerminateThread; end; {$ENDREGION} {$REGION 'thsTerminateThread'} thsTerminateThread: terminate; {$ENDREGION} end; end; end; procedure TTimeOutHandler.execute(); begin // inherited execute; executeStateMachine; end; {$ENDREGION} Ich hoffe jemand kann mir da helfen |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |