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 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.... ?!