Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Eigener Dienst beendet nicht korrekt... (https://www.delphipraxis.net/127539-eigener-dienst-beendet-nicht-korrekt.html)

cherry 15. Jan 2009 13:31

Re: Eigener Dienst beendet nicht korrekt...
 
Zitat:

Zitat von Dezipaitor
ServiceShutdown wird nur aufgerufen, wenn der Dienst von außen beendet werden soll, aber nicht wenn er sich beendet.
In ServiceShutdown musst du deine Prozedur ServiceExecute veranlassen aus der while-Schleife zu springen.
Dann kannst du am Ende von ServiceExecute dein Logging machen.

Es sieht so aus, als ob es nur deshalb manchmal geht, weil Windows deinen Dienst abschießt, da er nicht schnell genug aus ServiceExecute austritt. Ich sehe nämlich garkein Endbedingung.

ich hab mir mal das logfile angeschaut und dabei ist mir etwas aufgefallen:

Delphi-Quellcode:
2009-01-09 08:20:59 logfile created!
2009-01-09 08:20:59 Service successfully installed
2009-01-09 08:21:06 [administrator] logged in with IPAddress: 172.16.4.73
2009-01-09 08:21:06 [administrator] wrote "fast" logon info into database.
2009-01-09 08:21:26 [administrator] logged off

2009-01-09 08:23:05 [th21403] logged in with IPAddress: 172.16.4.73
2009-01-09 08:23:05 [th21403] wrote "full" logon info into database
2009-01-09 08:23:06 [th21403] 1 scan(s) has been automatically deleted!
2009-01-09 08:32:29 [th21403] logged off

2009-01-09 08:32:41 [ad_th21403] logged in with IPAddress: 172.16.4.73
2009-01-09 08:32:41 [ad_th21403] wrote "full" logon info into database
2009-01-09 08:35:32 [ad_th21403] logged off

2009-01-09 08:35:55 [ad_th21411] logged in with IPAddress: 172.16.4.73
2009-01-09 08:35:55 [ad_th21411] wrote "full" logon info into database
2009-01-09 08:37:51 [ad_th21411] logged off

2009-01-09 08:38:07 [th21403] logged in with IPAddress: 172.16.4.73
2009-01-09 08:38:07 [th21403] wrote "full" logon info into database
2009-01-09 08:38:07 [th21403] 1 scan(s) has been automatically deleted!
2009-01-09 08:39:09 [th21403] logged off

2009-01-09 08:39:11 [] Service shutdown

2009-01-09 09:10:35 [th21403] logged in with IPAddress: 172.16.4.73
2009-01-09 09:10:36 [th21403] wrote "full" logon info into database
2009-01-09 09:10:36 [th21403] 1 scan(s) has been automatically deleted!
2009-01-09 17:19:36 [th21403] logged off

2009-01-09 17:19:37 [] Service shutdown

2009-01-12 06:55:59 [th21403] logged in with IPAddress: 172.16.4.73
2009-01-12 06:56:01 [th21403] wrote "full" logon info into database
2009-01-12 06:56:01 [th21403] 1 scan(s) has been automatically deleted!
2009-01-12 15:58:19 [th21403] logged off

2009-01-12 15:58:20 [] Service shutdown

2009-01-13 06:54:55 [th21403] logged in with IPAddress: 172.16.4.73
2009-01-13 06:54:57 [th21403] wrote "full" logon info into database
2009-01-13 06:54:57 [th21403] 1 scan(s) has been automatically deleted!
2009-01-13 17:16:44 [th21403] logged off

2009-01-13 17:16:45 [] Service shutdown
und zwar ist mit aufgefallen, dass nur teilweise "[] Service shutdown" erscheint...
erscheint jetzt das nur wenn der dienst von windows abgewürgt wurde?

trotzdem erhalte ich immer ein "logged off" was eigentlich bedeutet, dass das logoff erfolgreich geschrieben wurde,
ist aber trotzdem nicht immer der Fall?!

nahpets 15. Jan 2009 13:44

Re: Eigener Dienst beendet nicht korrekt...
 
Hallo,

Zitat:

Zitat von Delphihilfe
Das Ereignis OnShutdown tritt ein, wenn das System, auf dem die Dienstanwendung läuft, heruntergefahren wird.

Das Ereignis OnStop tritt ein, wenn der Dienst vom Service Control Manager angehalten wird.

Zweite Variante entspricht net stop von der Console.

cherry 15. Jan 2009 15:29

Re: Eigener Dienst beendet nicht korrekt...
 
Ich hab jetzt mal eingebaut das Service Execute beendet wird wenn "onStop" oder "onShutdown" eintrifft. Das sieht aber ziemlich unschön aus, ist das wirklich die Lösung?

- bei meinen bisherigen Tests wurde zumindest bis jetzt das LogOout immer gemacht...
- leider kommt es manchmal zu einem Fehler wenn ich per net stop den Dienst beende... aber ich konnte nicht lokalisieren an
welcher stelle abgebrochen wird, trotz meiner {$IFDEF VERBOSE} ergänzung -> denn wenn die Meldung "Dienst konnte nicht beendet werden" kommt, wurde keine einzige meldung im log gemacht ab dem Zeitpunkt wo ich net stop eingebe...

Delphi-Quellcode:
procedure TMeinDienst.ServiceExecute(Sender: TService);
begin
  //ShowMessage('OnExecute - begin');
  while not Terminated do
  begin
    TRY
      // try to catch a user
      {$IFDEF VERBOSE}LogFile.Log(msg0049+'- in try block');{$ENDIF}
      if ShutDownNow then Exit;
      if Username <> '' then
      begin
        // AUTOSCAN
        // THIS SECTION IS FOR USER WHO JUST LOGGED IN
        if (Username <> GetSession) or (Welcome = False) then
        begin
          if ShutDownNow then Exit;
          {$IFDEF VERBOSE}LogFile.Log(msg0049+'before change username');{$ENDIF}
          ChangeUser;
          {$IFDEF VERBOSE}LogFile.Log(msg0049+'after change username');{$ENDIF}
          if Username <> '' then // its important to get sure that the username has really been catched
          begin
            if ShutDownNow then Exit;
            {$IFDEF VERBOSE}LogFile.Log(msg0049+'username is not equal to ""');{$ENDIF}
            Welcome := True;
            LogFile.Log(msg0004+GetIPAddress);
            // check if the user already exists in the database
            CheckDBforUser(ADOQuery1,ADOStoredProc1);
            if ShutDownNow then Exit;
            // Save to database that the user is logged in
            UpdateUserInfo(Username, true);
            if ShutDownNow then Exit;
            // get all info from User Table "t_bb_user"
            ADOQuery3.Close;
            ADOQuery3.Parameters.ParamValues['@username'] := username;
            ADOQuery3.Open;
            if ShutDownNow then Exit;
            {$IFDEF VERBOSE}LogFile.Log(msg0049+'passed cdfu and uui');{$ENDIF}
            // If the logged in user is not on the blacklist it will autoscan now
            if CheckUserOnBlacklist(Username) = False then
            begin
              if ShutDownNow then Exit;
              // autostart scan now, but first get defined scan_type from db!
              case ADOQuery3scan_type.AsInteger of
                0: begin ScanAndWriteToDB(True, stNoScanNoWrite); end;
                1: begin ScanAndWriteToDB(True, stFullScanWriteJustRootFoldersSize); end;
                2: begin ScanAndWriteToDB(True, stFullScanAndWrite); end;
              end;
            end
            else
            begin
              if ShutDownNow then Exit;
              // user is on blacklist, but login info will be saved
              ScanAndWriteToDB(True, stNoScanNoWrite);
              LogFile.Log(Username+msg0016);
            end;

            {$IFDEF VERBOSE}LogFile.Log(msg0049+'blacklist checked');{$ENDIF}

            // activate TCP server
            if ShutDownNow then Exit;
            if not assigned(TCPServer) then
              ActivateTCPServer;

          end;
        end
        else if StartManScan then
        begin
          {$IFDEF VERBOSE}LogFile.Log(msg0049+'man scan started');{$ENDIF}
          try
            // check if the user already exists in the database, else it will create him
            if Username <> '' then
            begin
              if ShutDownNow then Exit;
              CheckDBforUser(ADOQuery1,ADOStoredProc1);
              if ShutDownNow then Exit;
              ScanAndWriteToDB(False, stFullScanAndWrite);
              if ShutDownNow then Exit;
            end;
          finally
            // its very important to reset the variable StartManScan
            StartManScan := False;
            // send to the requesting host that the scan is complete now...
            Connect;
            TCPClient.IOHandler.WriteLn(IntToStr(CmdScanFinished));
            // disconnect
            Disconnect;
          end;
          if ShutDownNow then Exit;
        end;
      end
      else
      begin
        {$IFDEF VERBOSE}LogFile.Log(msg0049+'username ');{$ENDIF}
        if ShutDownNow then Exit;
        ChangeUser;
        Welcome := False;
      end;
    EXCEPT
      on e:Exception do
      begin
        LogFile.LOG(msg0000+e.Message);
        // maby there are some tcp actions pending...
        Disconnect;
        if fulllog then LogFile.Log(msg0039);
      end;
    END;
      ServiceThread.ProcessRequests(False);
      if ShutDownNow then Exit;
      {$IFDEF VERBOSE}LogFile.Log(msg0049+'BEGIN SLEEP');{$ENDIF}
      Sleep(1000);
      {$IFDEF VERBOSE}LogFile.Log(msg0049+'END SLEEP');{$ENDIF}
      if ShutDownNow then Exit;
  end;
  //ShowMessage('OnExecute - end');
end;
Ich denke das hat so gar nichts bewirkt... das Problem scheint, so denke ich, immer noch dies zu sein:

Zitat:

Zitat von Dezipaitor
ServiceShutdown wird nur aufgerufen, wenn der Dienst von außen beendet werden soll, aber nicht wenn er sich beendet.
In ServiceShutdown musst du deine Prozedur ServiceExecute veranlassen aus der while-Schleife zu springen.
Dann kannst du am Ende von ServiceExecute dein Logging machen.

Es sieht so aus, als ob es nur deshalb manchmal geht, weil Windows deinen Dienst abschießt, da er nicht schnell genug aus ServiceExecute austritt. Ich sehe nämlich garkein Endbedingung.

Und ich weiss nicht wie ich das nun machen soll.... ?!

nahpets 15. Jan 2009 16:22

Re: Eigener Dienst beendet nicht korrekt...
 
Hallo,

in der Delphihilfe heißt es im Beispiel:
Delphi-Quellcode:
while not Terminated do begin
**ServiceThread.ProcessRequests(True);
end;
bei Dir jedoch
Delphi-Quellcode:
  ServiceThread.ProcessRequests(False);
Habe gerade meine 3einhalb Service durchgeschaut, bei mir heißt's immer
Delphi-Quellcode:
ServiceThread.ProcessRequests(True)
und die verhalten sich (nach meinem Dafürhalten) alle ordentlich. Versuch' es doch bitte mal damit.
Zitat:

Zitat von Delphihilfe
VCL-Referenz
ProcessRequests (Methode von TServiceThread)

TServiceThread Methoden Siehe auch

Ermöglicht es Clients, den Dienst aufzurufen, der mit einem bestimmten Thread verknüpft ist.

Delphi-Syntax:

procedure ProcessRequests(WaitForMessage: Boolean);

C++ Syntax:

void __fastcall ProcessRequests(bool WaitForMessage);

Beschreibung

Die Methode ProcessRequests von TServiceThread wird in der Methode Execute aufgerufen, nachdem jede Ausführung der Ereignisbehandlungsroutine für OnExecute eines zugehörigen Dienstes beendet ist. Im Entwicklerhandbuch finden Sie weitere Informationen darüber, wie sich die Dienstausführung durch Abspaltung einzelner Threads für jede Dienstanforderung optimieren läßt.

Verstehe ich das richtig, dass bei ServiceThread.ProcessRequests(False) keine Messages abgearbeitet werden? Wenn dem so ist, warum darf Dein Service die Messages nicht abarbeiten? Wie erfährt er, dass er beendet werden soll oder dass das Betriebssystem herunter gefahren wird?

cherry 16. Feb 2009 09:31

Re: Eigener Dienst beendet nicht korrekt...
 
Zitat:

Zitat von nahpets

bei Dir jedoch
Delphi-Quellcode:
  ServiceThread.ProcessRequests(False);
Verstehe ich das richtig, dass bei ServiceThread.ProcessRequests(False) keine Messages abgearbeitet werden? Wenn dem so ist, warum darf Dein Service die Messages nicht abarbeiten? Wie erfährt er, dass er beendet werden soll oder dass das Betriebssystem herunter gefahren wird?

Wie genau das funktioniert weiss ich leider auch nicht, Tatsache ist aber, dass wenn ich True übergebe, der Dienst an dieser Stelle stehen bleibt und wahrscheinlich eine Message abwartet die er aber nicht erhält.

Die OnExecute Prozedur soll ja immer wieder ausgeführt werden, desshalb ist dort ja auch eine While Schliefe und ein Sleep(1000)
drin.

Oder mach ich dort grundsätzlich was falsch?

cherry 16. Feb 2009 09:43

Re: Eigener Dienst beendet nicht korrekt...
 
Hmm... Ich habs jetzt probeweise so gemacht:


Delphi-Quellcode:
ServiceThread.ProcessRequests(IsShuttingDownNow);

Die Variable IsShuttingDownNow ist von Anfang an auf False und wird dann in den Ereignissen
OnStop und OnShutdown auf True gesetzt.

Ist das richtig so?!

Angel4585 16. Feb 2009 10:28

Re: Eigener Dienst beendet nicht korrekt...
 
Wenn ich das recht verstehe ist das so:

ServiceThread.ProcessRequests(True); => Der Dienst wartet an dieser Stelle bis Messages da sind und bearbeitet diese dann
ServiceThread.ProcessRequests(False); => Der Dienst verarbeitet Messages, wenn keine da sind macht er einfach weiter

cherry 18. Feb 2009 14:14

Re: Eigener Dienst beendet nicht korrekt...
 
Zitat:

Zitat von Angel4585
Wenn ich das recht verstehe ist das so:

ServiceThread.ProcessRequests(True); => Der Dienst wartet an dieser Stelle bis Messages da sind und bearbeitet diese dann
ServiceThread.ProcessRequests(False); => Der Dienst verarbeitet Messages, wenn keine da sind macht er einfach weiter

Dann bist du mit meinem obigen Beitrag auch einverstanden?

Angel4585 18. Feb 2009 14:27

Re: Eigener Dienst beendet nicht korrekt...
 
ich würde die nicht auf true setzen.

meine Dienste sehen idR so aus:

Delphi-Quellcode:
procedure TMyDienst.Execute;
begin
while not terminated do
  begin
  //Irgendwas machen
  ServiceThread.ProcessRequests(False);
  end;
end;
OnShutdown usw belege ich erstmal garnicht.
Versuche dich mal ranzutasten wo bei dir das Problem liegt, also ein Minidienst machen und dann Stück für Stück einfügen und immerwieder zwischendurch testen obs geht

cherry 18. Feb 2009 14:32

Re: Eigener Dienst beendet nicht korrekt...
 
Zitat:

Zitat von Angel4585
OnShutdown usw belege ich erstmal garnicht.
Versuche dich mal ranzutasten wo bei dir das Problem liegt, also ein Minidienst machen und dann Stück für Stück einfügen und immerwieder zwischendurch testen obs geht

Tja da ist der Zug wohl abgefahren, mein Dienst umfasst nun bereits mehr als 1500 Zeilen Code und ist eingentlich so gut wie fertig. Ich habe den "Fehler" erst beim Testen bemerkt.

Beim starten des Dienst schreibt er in die Datenbank das er nun "online" ist.
Beim Beenden schreibt er in die Datenbank das er nicht mehr "online" ist...

Bis jetzt hatte ich ja eben auch immer auf False, aber dann schrieb er mir das LogOut manchmal nicht in die Datenbank.

hmm ich teste mal und meld mich dann mit meinen Ergebnissen wieder...


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:55 Uhr.
Seite 2 von 4     12 34      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz