![]() |
Anwendung --> Dienst erstellen
Hallo, brauche dringend ein bisschen Hilfe
Ich möchte, das ein Programm demnächst als Dienst läuft. Dieses Programm arbeitet mehrere Blöcke ab und wenn man das Programm beendet, soll der gerade aktuelle Block noch abgearbeitet werden. Das läuft soweit und ich bin soweit, dass auch die POberfläche so gut wie nicht mehr benutzt wird, nur noch das Kreuz zum Beenden des Programmes. Das habe ich ganz neu einen kleinen Dienst erstellt, der im Moment installiert werden kann, dann wird er gestartet, schreibt in eine Log-Datei Datum und Uhrzeit, kann auch wieder beendet werden und deinstalliert werden. Mein Problem besteht jetzt darin, wie ich die Funktionen in den Dienst bekomme. Wenn der Dienst gestartet wird soll die Methode Start von dem alten Programm aufgerufen werden, dann sollte das Programm wieder laufen und wenn ich den Dienst beende, dann soll die Methode Beenden des alten Programmes aufgerufen werden, damit der letzte aktuelle Block noch beendet werden kann und anschliessend soll der Dienst beendet werden. Wie mache ich das? Gruss Susanne |
Re: Anwendung --> Dienst erstellen
Hallo,
wenn ich das richtig verstehe soll er dienst im Hintergrund etwas vor sich hin rechnen solange der Rechner an ist? Ich würde dazu die Verarbeitung der Blöcke in einen Thread auslagern. Dieser wird dann beim Start des Dienstes angestoßen. Im Anhalte Ereignisses des Dienstes teilst du dem Thread dann mit das er doch bitte anhalten soll und wartest bis er fertig ist. Zum erstellen des Threads gibt es im Delphi unter Datei->Neu... ein kleines Symbol was das Grundgerüst erstellt. Deine Blockverarbeitung kommt dann in das Excute was dort schon angelegt rein, der Art:
Delphi-Quellcode:
Das starten vom Dienst aus sieht dann so aus:
procedure TWorkerThread.Execute(..);
begin while not Terminated do begin // hier immer einen Block abarbeiten end; end;
Delphi-Quellcode:
und zum beenden sollte das reichen:
myThread := TWorkerThread.Create(false);
Delphi-Quellcode:
So hoffe das gibt dir erstmal ein paar Ansatzpunkte... ansonsten gabs hier noch irgendwo ein Tutorial zum Thema Threads... ich bin aber so vergeßlich - wird sicher noch jemand die URL posten.
if Assigned(myThread) then
begin myThread.Terminated; myThread.WaitFor; FreeAndNil(myThread); end; |
Re: Anwendung --> Dienst erstellen
Hab noch nie mit Threads gearbeitet, deshalb auch noch mal ein paar Fragen mehr zum Verständnis.
Gut, das hat mir schon ein ganzes Stück weiter geholfen. Ich habe nun die Bestehende Klasse, so wie sie bisher alleine lief in einen Thread gepackt, mittlerweile gibt es auch keine CompilerFehler mehr. In myThread.Execute packe ich dann die Funktion, die die ganze Abarbeitung der Blöcke steuert. Ist das richtig? und in die Unit des Dienstes in der Methode onStart kommt dann dieses rein, und dadurch wird der Thread dann gestartet?
Delphi-Quellcode:
myThread := TWorkerThread.Create(false);
Ich habe auch noch zwei Timer in der BlockVerarbeitung mit drin, muss ich da noch was besonderes beachten? Und der folgende Teil kommt dann bei onStop-Ereignis des Dienstes rein?
Delphi-Quellcode:
solange der Thread also nicht beendet wurde läuft er immer wieder durch die Schleife, wenn ich nun den Dienst beende sage ich dem Thread durch den Assigned-Teil, dass er beendet werden soll und er geht aus der Schleife raus? und ruft dann FormCloseQuery aus?
if Assigned(myThread) then
begin myThread.Terminated; myThread.WaitFor; FreeAndNil(myThread); end;
Delphi-Quellcode:
Frage: FormCreate läuft eigentlich auch in einer endlos-Schleife, Füher hat er das Signal zum sich beenden durch das Klicken auf das Kreuz des Fensters bekommen. Und das FormCreate lief auch nicht in einer Schleife.
procedure TimeManagerThread.Execute;
begin while not Terminated do begin FormCreate; end; FormCloseQuery; { Thread-Code hier einfügen } end; wäre dann vielleicht auch das möglich bzw, Sinnvoller? ich hab was von einer Methode Terminate gelesen, kann ich die dann nicht eventuell aufrufen?
Delphi-Quellcode:
und alles was ich in meinen Dienst reingepackt habe wie wie die oberen beiden Sachen, die meckert er an, wie
procedure TimeManagerThread.Execute;
begin FormCreate; if terminated then FormCloseQuery; end; Undefinierter Bezeichner: 'TMThread' Operator oder Semikolon fehlt |
Re: Anwendung --> Dienst erstellen
Hallo,
Zitat:
Zitat:
![]() ![]() Zitat:
Zitat:
Zitat:
|
Re: Anwendung --> Dienst erstellen
Die beiden Timer im Thread sind zum Steuern der einzelnen Funktionen bei der Abarbeitung der Blöcke da und es ist auch sonst nichts mehr auf dem Form, das Form sollte ja auch ganz verschwinden durch diesen Dienst, der User soll auch nicht darin herum klicken.
Ich kann mittlerweile den Dienst installieren und der Thread wird anscheinend auch gestartet, aber irgendwo muss er am Anfang beim initialisieren hängen bleiben und macht nicht mehr weiter. |
Re: Anwendung --> Dienst erstellen
Hallo,
kannst du es nicht so umprogrammieren das du die Timer garnicht mehr brauchst und dann das ganze Formularzeugs rauswerfen? Das er da hängen bleibt ist denke ich erstmal nicht sooo verwunderlich. |
Re: Anwendung --> Dienst erstellen
Bei dem zweiten Timer weiss ich wie ich es machen könnte ihn zu umgehen, das ist nicht unbedingt ein Problem, bei dem erst weiss ich nicht so genau, wie ich es machen könnte.
Der Timer ruft die Funktion TimerTimer in bestimmten Abständen auf, wenn in der Funktion dann verarbeitet wird der Timer abgeschaltet, nach der Verarbeitung wieder angeschaltet. Vielleicht sehe ich auch im Moment den Wald vor lauter Bäumen nicht mehr. |
Re: Anwendung --> Dienst erstellen
Ich glaube, den Thread selber habe ich am Laufen. Ich habe das ganze jetzt mit einer einfach normalen Anwendung ausprobiert, damit funktioniert es nun, ohne Probleme. Beide Varianten habe keine Timer und nichts unötiges.
Delphi-Quellcode:
Damit bin ich mir erst mal sicher, dass der Thread läuft. Nun habe ich das ganze nochmal mit dem Dienst probiert.
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Thread; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; TThread: TimeManagerThread; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin TThread:= TimeManagerThread.Create (false); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(TThread) then begin {TMThread.Terminated;} TThread.Terminate; //kehrt erst zurück, wenn Thread beendet ist! //TThread.WaitFor; //Freigeben des Threads FreeAndNil(TThread); end end; end.
Delphi-Quellcode:
Und hier funktioniert das ganze natürlich nicht richtig. im OnStart habe ich ServiceStart zugeordnet und onstop Servicestop. installieren, deinstallieren macht er, er startet auch, aber es passiert nichts, er müsste eine Anwendung öffnen. Wenn ich dann den Dienst beende kommt folgende Fehlermeldung
unit Dienst;
interface uses Windows, Messages, extctrls, WinSvc, SysUtils, Classes, Graphics, Controls, SvcMgr, ShellAPI, Dialogs, Thread; type TTimeManagerService = class(TService) {Initialisierung des TimeManagerServices} procedure ServiceStart(Sender: TService; var Started: Boolean); {Deinitialisierung des TimeManagerServices} procedure ServiceStop(Sender: TService; var Stopped: Boolean); {hier erfolgt die Steuerung des Dienstes} procedure ServiceExecute(Sender: TService); private { Private-Deklarationen } public function GetServiceController: TServiceController; override; { Public-Deklarationen } end; var TimeManagerService: TTimeManagerService; TMThread: TimeManagerThread; implementation {$R *.DFM} procedure ServiceController(CtrlCode: DWord); stdcall; begin TimeManagerService.Controller(CtrlCode); end; function TTimeManagerService.GetServiceController: TServiceController; begin Result := ServiceController; end; //Initialisierung des TimeManagerServices procedure TTimeManagerService.ServiceStart(Sender: TService; var Started: Boolean); begin TMThread:= TimeManagerThread.Create(false); end; //DeInitialisierung des TimeManagerServices procedure TTimeManagerService.ServiceStop(Sender: TService; var Stopped: Boolean); begin //Hier müsste dann der TimeManagerTeil CloseQueryForm aufgerufen werden if Assigned(TMThread) then begin {TMThread.Terminated;} TMThread.TerminateThread; //kehrt erst zurück, wenn Thread beendet ist! //TMThread.WaitFor; //Freigeben des Threads FreeAndNil(TMThread); end; end; //Steuerung des Dienstes procedure TTimeManagerService.ServiceExecute(Sender: TService); begin while not Terminated do ServiceThread.ProcessRequests(True); end; end. Dienst auf lokaler comüuter konnt nicht bendetwerden, Kein Fehler zurück gegeben, kann interne Windows-Fehler sein, oder interner Dienst fehler Im TaskManager unter Prozesse ist er auch immernoch vorhanden. Wo verflucht nochmal ist denn nun noch was,was ziemlich schief läuft? |
Re: Anwendung --> Dienst erstellen
Hallo,
die Dienste laufen im Hintergrund und können keine Oberfläche haben die der Benutzer sieht (gut es gibt auch Ausnahmen...). Wenn du dann trotzdem versuchst ein Formular zu erstellen wird das sicher schiefgehen! |
Re: Anwendung --> Dienst erstellen
Es soll kein Formular geöffnet werden, einfach irgendein Programm, z.B. Word. Geht das auch nicht?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:44 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