Daemon läuft nicht an

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Holger.D
Beiträge: 6
Registriert: Di 8. Nov 2011, 11:19
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Daemon läuft nicht an

Beitrag von Holger.D »

Hallo alle zusammen,

ich möchte gerne unter Lazarus einen Dienst schreiben. Den Test-Dienst im Anhang hab ich so weit, dass Install und Uninstall klappt. Wenn ich den Dienst mit der Dienstverwaltung von Windows starte wird er zwar ausgeführt, aber ich kann keine Aktion erkennen. Starte ich die Dienst-EXE mit dem Parameter -r bekomme ich im Log-File die Meldung:

DaemonTest [2011-11-22 15:44:20.174 Error] Failed to start service manager: Der Dienstprozess konnte keine Verbindung mit dem Dienstcontroller herstellen.

Bitte helft mir, ich komme einfach nicht mehr weiter....

Holger
Dateianhänge
TestDaemon.zip
(3.07 KiB) 94-mal heruntergeladen

Benutzeravatar
theo
Beiträge: 10498
Registriert: Mo 11. Sep 2006, 19:01

Re: Daemon läuft nicht an

Beitrag von theo »

Kann mich dumpf erinnern, dass man da jeweils ins Ereignisprotokoll schauen muss.
Hast du das getan?

Holger.D
Beiträge: 6
Registriert: Di 8. Nov 2011, 11:19
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Daemon läuft nicht an

Beitrag von Holger.D »

Hab gerade mal in die Windows-Ereignisanzeige rein geschaut und dort nur die Meldungen gesehen, dass der Dienst gestartet oder gestoppt wurde.

Holger

Benutzeravatar
theo
Beiträge: 10498
Registriert: Mo 11. Sep 2006, 19:01

Re: Daemon läuft nicht an

Beitrag von theo »

Hab nur kurz in die Quellen reingeschaut.
Wo startest du denn den Thread (FThread.Resume) ?

Holger.D
Beiträge: 6
Registriert: Di 8. Nov 2011, 11:19
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Daemon läuft nicht an

Beitrag von Holger.D »

Moin,

ja, Resume hatte ich vergessen, aber wenn ich sie in die Funktion einfüge ändert sich nichts.

Code: Alles auswählen

function TDaemon1.Start: Boolean;
begin
   Result:=inherited Start;
   AWriteln('Daemon  Start  ',Result);
   FThread:=TTestThread.Create(True);
   FThread.OnTerminate:=@ThreadStopped;
   FThread.FreeOnTerminate:=False;
   FThread.Resume;
end;


Im Debugger sehe ich , dass die Funktion TDaemon1.Start gar nicht angesprungen wird.

Holger

Holger.D
Beiträge: 6
Registriert: Di 8. Nov 2011, 11:19
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Daemon läuft nicht an

Beitrag von Holger.D »

Hallo,

gibt es keinen der mir helfen kann?
Läuft mein Test-Dienst bei euch?
Kann mir jemand eine funktionierenden Test-Dienst zur Verfügung stellen?


Holger

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: Daemon läuft nicht an

Beitrag von gocher »

Hallo zusammen,
ich weiß nicht ob sich jemand noch einmal mit dem Daemon Problem befasst hat, also bei mir sieht es unter Windows 7 nun so aus:

Code: Alles auswählen

program thedaemon;
 
{$mode objfpc}{$H+}
 
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
  CThreads,
{$ENDIF} Cmem,{$ENDIF}
  Classes, SysUtils, EventLog, DaemonApp;
 
type
  TTheThread = class(TThread)
  public
    procedure Execute; override;
  end;
 
  TTheDaemon = class(TCustomDaemon)
  private
    FThread: TTheThread;
  public
    function Install: boolean; override;
    function UnInstall: boolean; override;
    function Start: boolean; override;
    function Stop: boolean; override;
    function Pause: boolean; override;
    function Continue: boolean; override;
    function Execute: boolean; override;
    function ShutDown: boolean; override;
  end;
 
  TTheDaemonMapper = class(TCustomDaemonMapper)
  public
    constructor Create(AOwner: TComponent); override;
    procedure ToDoOnInstall(Sender: TObject);
    procedure ToDoOnRun(Sender: TObject);
    procedure ToDoOnUninstall(Sender: TObject);
    procedure ToDoOnDestroy(Sender: TObject);
  end;
 
function BoolToStr(AVal: Boolean): String;
begin
  if AVal = True then result := 'true' else result := 'false';
end;
 
procedure TTheThread.Execute;
var i: integer;
begin
  i := 0;
  Application.Log(etDebug, 'Thread.Execute');
  try
    repeat
      Sleep(1000); //milliseconds
      inc(i);
      Application.Log(etDebug, 'Thread.Loop ' + Format('Tick :%d', [i]));
    until Terminated;
    Application.Log(etDebug, 'Thread.LoopStopped');
  except
    on E: Exception do
      Application.Log(etError, 'Thread.Execute: ' + E.Message);
  end;
end;
 
{$REGION ' - Daemon - '}
function TTheDaemon.Install: boolean;
begin
  result := inherited Install;
  Application.Log(etDebug, 'Daemon.installed: ' + BoolToStr(result));
end;
 
function TTheDaemon.UnInstall: boolean;
begin
  result := inherited UnInstall;
  Application.Log(etDebug, 'Daemon.Uninstall: ' + BoolToStr(result));
end;
 
function TTheDaemon.Start: boolean;
begin
  result := inherited Start;
  Application.Log(etDebug, 'Daemon.Start: ' + BoolToStr(result));
  if not(assigned(FThread)) then
  begin
    FThread := TTheThread.Create(true);
    FThread.FreeOnTerminate := true;
    FThread.Resume;
  end;
end;
 
function TTheDaemon.Stop: boolean;
begin
  Application.Log(etDebug, 'Daemon.Stop: ' + BoolToStr(result));
  if assigned(FThread) then
  begin
    FThread.Terminate;
    Application.Log(etDebug, 'Thread.WaitFor');
    FThread.WaitFor;
    Application.Log(etDebug, 'Thread.Free');
    FThread := nil;
  end;
  result := inherited Stop;
end;
 
function TTheDaemon.Pause: boolean;
begin
  result := inherited Pause;
  Application.Log(etDebug, 'Daemon.Pause: ' + BoolToStr(result));
  if assigned(FThread) then
    FThread.Suspend;
end;
 
function TTheDaemon.Continue: boolean;
begin
  result := inherited Continue;
  Application.Log(etDebug, 'Daemon.Continue: ' + BoolToStr(result));
  if assigned(FThread) then
    FThread.Resume;
end;
 
function TTheDaemon.Execute: boolean;
begin
  result := inherited Execute;
  Application.Log(etDebug, 'Daemon.Execute: ' + BoolToStr(result));
end;
 
function TTheDaemon.ShutDown: boolean;
begin
  result := inherited ShutDown;
  Application.Log(etDebug, 'Daemon.ShutDown: ' + BoolToStr(result));
end;
{$ENDREGION}
 
{$REGION ' - DaemonMapper - '}
constructor TTheDaemonMapper.Create(AOwner: TComponent);
begin
  Application.Log(etDebug, 'DaemonMapper.Create');
  inherited Create(AOwner);
  with DaemonDefs.Add as TDaemonDef do
  begin
    DaemonClassName := 'TTheDaemon';
    Name := 'theDaemon.exe';
    Description := 'The Daemon Exsample';
    DisplayName := 'The Daemon';
    Options := [doAllowStop,doAllowPause];
    Enabled := true;
    with WinBindings do
    begin
      StartType := stBoot;
      WaitHint := 0;
      IDTag := 0;
      ServiceType := stWin32;
      ErrorSeverity := esNormal;//esIgnore;
    end;
    LogStatusReport := false;
  end;
  OnInstall := @Self.ToDoOnInstall;
  OnRun := @Self.ToDoOnRun;
  OnUnInstall := @Self.ToDoOnUninstall;
  OnDestroy := @Self.ToDoOnDestroy;
  Application.Log(etDebug, 'DaemonMapper.Createted');
end;
 
procedure TTheDaemonMapper.ToDoOnInstall(Sender: TObject);
begin
  Application.Log(etDebug, 'DaemonMapper.Install');
end;
 
procedure TTheDaemonMapper.ToDoOnRun(Sender: TObject);
begin
  Application.Log(etDebug, 'DaemonMapper.Run');
end;
 
procedure TTheDaemonMapper.ToDoOnUnInstall(Sender: TObject);
begin
  Application.Log(etDebug, 'DaemonMapper.Uninstall');
end;
 
procedure TTheDaemonMapper.ToDoOnDestroy(Sender: TObject);
begin
  //doesn't comes here
  Application.Log(etDebug, 'DaemonMapper.Destroy');
end;
{$ENDREGION}
 
{$R *.res}
 
begin
  heaptrc.SetHeapTraceOutput(ChangeFileExt(ParamStr(0), '.heap'));
  RegisterDaemonClass(TTheDaemon);
  RegisterDaemonMapper(TTheDaemonMapper);
  with Application do
  begin
    Title := 'Daemon Application';
    EventLog.LogType := ltFile;
    EventLog.DefaultEventType := etDebug;
    EventLog.AppendContent := true;
    EventLog.FileName := ChangeFileExt(ParamStr(0), '.log');
    Initialize;
    Run;
  end;
end.


Der Logfile enthält die folgenden Passagen:

\thedaemon.exe --install
theDaemon [2013-02-28 21:42:03.750 Debug] DaemonMapper.Create
theDaemon [2013-02-28 21:42:03.750 Debug] DaemonMapper.Createted
theDaemon [2013-02-28 21:42:03.750 Debug] DaemonMapper.Install
theDaemon [2013-02-28 21:42:03.875 Debug] Daemon.installed: true

dienste: start
theDaemon [2013-02-28 21:42:12.018 Debug] DaemonMapper.Create
theDaemon [2013-02-28 21:42:12.018 Debug] DaemonMapper.Createted
theDaemon [2013-02-28 21:42:12.018 Debug] DaemonMapper.Run
theDaemon [2013-02-28 21:42:12.018 Info] Daemon The Daemon current status: Start Pending
theDaemon [2013-02-28 21:42:12.018 Debug] Daemon.Start: true
theDaemon [2013-02-28 21:42:12.018 Info] Daemon The Daemon current status: Running
theDaemon [2013-02-28 21:42:12.018 Debug] Thread.Execute
theDaemon [2013-02-28 21:42:12.018 Debug] Daemon.Execute: false
theDaemon [2013-02-28 21:42:13.028 Debug] Thread.Loop Tick :1
theDaemon [2013-02-28 21:42:14.042 Debug] Thread.Loop Tick :2
theDaemon [2013-02-28 21:42:15.056 Debug] Thread.Loop Tick :3
theDaemon [2013-02-28 21:42:16.070 Debug] Thread.Loop Tick :4
theDaemon [2013-02-28 21:42:17.084 Debug] Thread.Loop Tick :5
theDaemon [2013-02-28 21:42:18.098 Debug] Thread.Loop Tick :6

dienste: pause
theDaemon [2013-02-28 21:42:18.223 Info] Daemon The Daemon current status: Pause Pending
theDaemon [2013-02-28 21:42:18.223 Debug] Daemon.Pause: true
theDaemon [2013-02-28 21:42:18.223 Info] Daemon The Daemon current status: Paused

dienste: continue
theDaemon [2013-02-28 21:42:23.026 Info] Daemon The Daemon current status: Continue Pending
theDaemon [2013-02-28 21:42:23.042 Debug] Daemon.Continue: true
theDaemon [2013-02-28 21:42:23.042 Info] Daemon The Daemon current status: Running
theDaemon [2013-02-28 21:42:23.042 Debug] Thread.Loop Tick :7
theDaemon [2013-02-28 21:42:24.049 Debug] Thread.Loop Tick :8
theDaemon [2013-02-28 21:42:25.063 Debug] Thread.Loop Tick :9
theDaemon [2013-02-28 21:42:26.077 Debug] Thread.Loop Tick :10
theDaemon [2013-02-28 21:42:27.091 Debug] Thread.Loop Tick :11

dienste: stop
theDaemon [2013-02-28 21:42:27.340 Info] Daemon The Daemon current status: Stop Pending
theDaemon [2013-02-28 21:42:27.340 Debug] Daemon.Stop: true
theDaemon [2013-02-28 21:42:27.340 Debug] Thread.WaitFor
theDaemon [2013-02-28 21:42:28.103 Debug] Thread.Loop Tick :12
theDaemon [2013-02-28 21:42:28.103 Debug] Thread.LoopStopped
theDaemon [2013-02-28 21:42:28.103 Debug] Thread.Free
theDaemon [2013-02-28 21:42:28.103 Info] Daemon The Daemon current status: Stopped

/thedaemon.exe --uninstall
theDaemon [2013-02-28 21:42:34.156 Debug] DaemonMapper.Create
theDaemon [2013-02-28 21:42:34.156 Debug] DaemonMapper.Createted
theDaemon [2013-02-28 21:42:34.156 Debug] DaemonMapper.Uninstall
theDaemon [2013-02-28 21:42:34.156 Debug] Daemon.Uninstall: true

Leider scheint beim DaemonMapper der Destructor nie ausgeführt zu werden oder mache ich einen Denkfehler, der Thread wird nun richtig beendet!
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Antworten