![]() |
Windows Dienst starten und beenden, interval
Hallo,
ich habe anhand diverser Beiträge hier aus dem Forum mal einen eigenen Dienst/Service für Windows XP geschrieben, soweit so gut klappt auch alles. Ich installiere den Dienst per Dienst.exe /install und starten tu ich im moment noch per Verwaltung -> Dienste -> Rechts klick auf meinen Dienst -> starten. Jetzt kommen 2 Fragen auf, wie starte ich den Dienst direkt weil beim installieren ist dieser ja noch nicht gestartet ?! Ich bin am überlegen ein batch script oder programm im Autostart oder der gleichen zu hinterlegen was mir meinen Dienst startet oder wenn möglich den Dienst direkt dort einfügen. Das zweite Problem, gehe ich jetzt in die Dienstverwaltung und klicke auf Beenden erhalte ich eine Fehlermeldung, das der Dienst nicht korrekt beendet werden konnte usw. Hier mal der Quelltext zu meinem Dienst, der Dienst ist mit Turbo Delphi Explorer erstellt worden.
Delphi-Quellcode:
Was der Dienst einfach machen soll ist alle paar Minuten alle Dateien aus einem Verzeichnis prüfen ob deren Inhalt
unit uMain;
interface Const DelayTime = 5; //Zeitinterval in minuten DIR_MESSANZ = '\\server2\daten_public\daten\mess_anz\'; FILE_LOG = 'D:\Source\Projekte\Dienst\service.log'; MOD_Sys = 'Service'; MOD_MessAnz = 'Mess_Anz'; uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, DBXpress, WideStrings, DB, SqlExpr, uTools, MD5; type TService1 = class(TService) SQLCon: TSQLConnection; procedure ServiceExecute(Sender: TService); private { Private-Deklarationen } procedure pUpdateMessAnz; procedure pLog(Modul, strMsg: String); public function GetServiceController: TServiceController; override; { Public-Deklarationen } end; var Service1: TService1; implementation {$R *.DFM} procedure ServiceController(CtrlCode: DWord); stdcall; begin Service1.Controller(CtrlCode); end; function TService1.GetServiceController: TServiceController; begin Result := ServiceController; end; procedure TService1.ServiceExecute(Sender: TService); begin While NOT Terminated Do Begin ServiceThread.ProcessRequests(False); //Datenbank verbindung öffnen If NOT SQLCon.Connected Then Begin Try SQLCon.Open; Except On E: Exception Do Begin pLog(MOD_Sys, 'Fehler beim Verbinden mit der Datenbank!'); pLog(MOD_Sys, E.Message); End; End; End; //Update Routinen ausführen... If SQLCon.Connected Then Begin pLog(MOD_Sys, 'Beginne Update'); pUpdateMessAnz; End;{if} //Verbindung beenden falls noch offen... If SQLCon.Connected Then SQLCon.Close; //Service schlafen legen ... Sleep(1000 * 60 * DelayTime); End;{while} end; procedure TService1.pUpdateMessAnz; begin //mySQL Datenbank update... end; procedure TService1.pLog(Modul, strMsg: string); var FHandle : Text; begin System.Assign(FHandle, FILE_LOG); {$I-} If FileExists(FILE_LOG) Then Append(FHandle) Else Rewrite(FHandle); {$I+} If IoResult = 0 Then Begin Writeln(FHandle, DateTimeToStr(Now)+' '+Modul+': '+strMsg); System.Close(FHandle); End;{if} end; end. in einer Datenbank eingetragen ist. Mir scheint es da ein Problem mit der Sleep() Anweisung zu geben jedoch wüßte ich grade keine alternative wie ich es schaffe das der Dienst nur alle paar minuten prüft und nicht in einem durch. mfg TUX |
Re: Windows Dienst starten und beenden, interval
Du könntest einen Timer verwenden ... stehe beim Beenden aber vor dem selben Problem, muss den Dienst immer durch Taskmanager oder Prozess-Explorer killen.
[Nachtrag] Die Lösung des Problems findest Du hier: ![]() [/Nachtrag] [Nachtrag2] Kein roter Kasten. [/Nachtrag2] |
Re: Windows Dienst starten und beenden, interval
Setze nach dem Beenden mal den ServiceState (oder war's nur State? man, ist schon lange her) mal auf 'Stopped'. Dann sollte zumindest der Fehler beim Beenden nicht mehr kommen.
|
Re: Windows Dienst starten und beenden, interval
Liste der Anhänge anzeigen (Anzahl: 1)
Verwende ich wie in dem Beitrag auf den GuenterS verwiesen hat eine der Prozeduren
OnStart bzw. OnStop dann erhalte ich eine Fehlermeldung beim Starten, siehe Anlage laufen tut der Dienst zwar aber nur einmal danach ist er nicht mehr gestartet ... Marabu hat zwar auch in dem Beitrag geschrieben das es gehen müßte ...
Delphi-Quellcode:
Jedoch weiß ich nicht wo und wie man dann Active wieder auf False setzt, im OnStop
procedure TObserver.ServiceExecute(Sender: TService);
begin Log('Guardian executing'); while Active do begin Sleep(1000); if Abs(Now - LastCheck) > Interval then begin CheckTargetService(ServiceName); LastCheck := Now; end; ServiceThread.ProcessRequests(false); end; end; Ereignis bekommt man ja wieder den gleichen Fehler. Gibt es den nirgendwo ein Beispiel Gerüst wo man eigentlich nur noch seine Prozeduren einfügen muß, dann könnte ich mal sehen wie es funktioniert. :? Ich hab noch folgendes gefunden was ich mir mal ansehen werde ![]() |
Re: Windows Dienst starten und beenden, interval
Das mit dem Service geht mir leider genauso. Der Thread wird zwar gestartet, aber leider wird der Dienst sofort wieder beendet. ICh könnte zwar mittels WaitFor eintragen, aber ob das mit der Steuerung dann besser geht?
|
Re: Windows Dienst starten und beenden, interval
So ich glaub ich hab jetzt alles, ich kann meinen Service starten, beenden und sogar anhalten ohne
irgendwelche Fehlermeldungen zu bekommen.
Delphi-Quellcode:
Desweiteren habe ich in meiner pUpdateMessAnz Prozedure eine Repeat Until schleife die auch auf den Status reagiert,
unit uMain;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, ExtCtrls, DBXpress, WideStrings, DB, SqlExpr; type TSvc = class(TService) Timer: TTimer; SQLCon: TSQLConnection; procedure ServiceContinue(Sender: TService; var Continued: Boolean); procedure ServiceExecute(Sender: TService); procedure ServicePause(Sender: TService; var Paused: Boolean); procedure ServiceStart(Sender: TService; var Started: Boolean); procedure ServiceStop(Sender: TService; var Stopped: Boolean); procedure TimerTimer(Sender: TObject); private { Private-Deklarationen } public function GetServiceController: TServiceController; override; { Public-Deklarationen } end; var Svc: TSvc; implementation uses uGlobal, uHandling_File, uHandling_Updates; {$R *.DFM} procedure ServiceController(CtrlCode: DWord); stdcall; begin Svc.Controller(CtrlCode); end; function TSvc.GetServiceController: TServiceController; begin Result := ServiceController; end; procedure TSvc.ServiceContinue(Sender: TService; var Continued: Boolean); begin Continued := True; end; procedure TSvc.ServiceExecute(Sender: TService); begin //Service läuft die ganze Zeit und Wartet auf Anfragen... False ergibt 100% Auslastung, True nicht While NOT Terminated Do Begin ServiceThread.ProcessRequests(True); End;{while} end; procedure TSvc.ServicePause(Sender: TService; var Paused: Boolean); begin Paused := True; end; procedure TSvc.ServiceStart(Sender: TService; var Started: Boolean); begin Started := True; Timer.Interval := 1000; Timer.Enabled := True; pLog(True, MOD_SYS, 'Service wird gestartet...'); end; procedure TSvc.ServiceStop(Sender: TService; var Stopped: Boolean); begin Stopped := True; pLog(True, MOD_SYS, 'Service wird beendet...'); end; procedure TSvc.TimerTimer(Sender: TObject); begin //Timer für die Zeit der verarbeitung abschalten Timer.Enabled := False; //Timer Interval setzen... Timer.Interval := 1000 * 60 * DelayTime; //Datenbank verbindung öffnen If NOT SQLCon.Connected Then Begin Try SQLCon.Open; Except On E: Exception Do Begin pLog(True, MOD_Sys, 'Fehler beim Verbinden mit der Datenbank!'); pLog(True, MOD_Sys, E.Message); End;{on} End;{try} End;{if} If SQLCon.Connected Then Begin //Update Routinen ausführen... pUpdateMessAnz; //Verbindung beenden falls noch offen... SQLCon.Close; End;{if} //Timer wieder einschalten Timer.Enabled := True; end; end. sonst läuft die Schleife weiter obwohl man den Dienst beendet bzw. angehalten hat.
Delphi-Quellcode:
Was ich mir jetzt noch einfallen lassen muß wie ich den Service gestartet bekomme .. vielleicht direkt beim installieren
procedure pUpdateMessAnz;
begin If SysUtils.FindFirst(DIR_MESSANZ+'????????.??M', faAnyFile, FileInfo) = 0 Then Begin Repeat //.. Until (SysUtils.FindNext(FileInfo) <> 0) Or (Svc.Status <> csRunning); SysUtils.FindClose(FileInfo); End;{if} end; oder von einem Ext. Programm oder Batch script ('net start service_name') .. mal schauen. |
Re: Windows Dienst starten und beenden, interval
Fürs starten könntest Du die Startart von manual auf automatic stellen.
|
Re: Windows Dienst starten und beenden, interval
Ich habe folgendes eingestellt...
ServiceType = stWin32 StartType = stAuto Wenn ich das so stehen habe brauche ich nur in der Diensteverwaltung auf meinen Dienst mit der rechten Maustaste klicken und Starten wählen. Ich muß mal testen was die einzelnen einstellungen bedeuten, evtl. StartType auf stBoot stellen. |
Re: Windows Dienst starten und beenden, interval
Das kannst Du doch auch schon wenn Startart Manuell ist ? *grübel*
|
Re: Windows Dienst starten und beenden, interval
Was ich mit der aktion erreichen will ist das ich wissen will ob allein durch
Service.exe /install der Dienst nicht nur installiert wird sondern auch gleichzeitig gestartet werden kann oder ist dies nicht möglich so das ich so oder so noch ein weiters programm benötige was dies erledigt oder ich das von hand per Dienstverwaltung erledige. Nachtrag: Ich habe einen ![]() Frage. Ich werde das manuell starten, da der Dienst eh nur für mich ist brauche ich auch keinen komfort. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz