Thema: Delphi Dienst "wird beendet"

Einzelnen Beitrag anzeigen

Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#10

Re: Dienst "wird beendet"

  Alt 12. Mär 2010, 12:33
Es gibt einige Probleme mit den Shellfunktionen, wenn man sie aus einem Dienst startet.

Man kann einen Dienst ganz einfach beenden, indem man die Executemethode verlässt.
In den JWSCL Beispielen gibt es einige Dienste, die Pipes verwenden (ja sogar mehrere) und auf deren Ende warten und trotzdem die Dienstmanagernachrichten beantworten. (z.B. unvollendete Projekt: XPElevation -> MainUnit.pas)

Delphi-Quellcode:
   try //except
      try
        fThreadsStoppedEvent := CreateEvent(nil, true, false, nil);
        fServiceStopEvent := CreateEvent(nil, true, false, nil);
        Sleep(1000);


        ZeroMemory(@OvLapped, sizeof(OvLapped));
        OvLapped.hEvent := CreateEvent(nil, false, false, nil);
...

          try
            Pipe := CreateServicePipe(Log);
            repeat
              ConnectNamedPipe(Pipe, @OvLapped);

              repeat
                if Assigned(ServiceThread) then
                  ServiceThread.ProcessRequests(False);


                if (TJwWindowsVersion.IsWindowsXP(true) or
                    TJwWindowsVersion.IsWindows2003(true)) and
                      (GetSystemMetrics(SM_SHUTTINGDOWN) <> 0) then
                    Stopped := true;

                SetLastError(0);
                WaitResult := JwMsgWaitForMultipleObjects([fServiceStopEvent, OvLapped.hEvent], false, INFINITE, QS_ALLINPUT);

                case WaitResult of
                  WAIT_OBJECT_0 + 1 : ResetEvent(OvLapped.hEvent);
                  WAIT_OBJECT_0 + 2 : PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE); //tag message as read
                else
                  OutputDebugString(PChar(IntToStr(GetLastError)));
                end;

              until WaitResult <> WAIT_OBJECT_0 + 2; //
              
              if WaitResult = WAIT_OBJECT_0 +1 then //OvLapped.hEvent
              begin
                ...
                {We use this pipe only a very short time so it is very unlikely
                that several clients are going to connect at the same time.
                }

                PipeName := THandleRequestThread.CreatePipeName(UniquePipeID);
                
                ReadFile(Pipe, @ProtocolVersion, sizeof(ProtocolVersion) ,nil, @OvLapped2);

                if JwWaitForMultipleObjects([fServiceStopEvent, OvLapped2.hEvent], false,
                      {$IFNDEF DEBUG}1000{$ELSE}INFINITE{$ENDIF}) = WAIT_OBJECT_0 +1 then
                begin
... //Pipeclient und extra Thread übergeben.
                end;
...
...
              Sleep(5000);
              DisconnectNamedPipe(Pipe);

            until Stopped;

          finally
//signal server shutdown
            Stopped := true;

            {Wait for all threads to be stopped or timeout
            Set by a method that is called by threads which are finished.
            It decreases a value down to 0 and then fires the event.
            }

            WaitForSingleObject(ThreadsStopEvent, 30 * 1000);
          
            fPasswords.Free;
          end;
Und manuelles Stopereignis:
Delphi-Quellcode:
procedure TXPService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  SetEvent(fServiceStopEvent);
end;
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat