AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Anwendung --> Dienst erstellen

Ein Thema von Susanne · begonnen am 27. Okt 2004 · letzter Beitrag vom 28. Okt 2004
Antwort Antwort
Seite 1 von 2  1 2      
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#1

Anwendung --> Dienst erstellen

  Alt 27. Okt 2004, 15:44
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
Susanne
  Mit Zitat antworten Zitat
Benutzerbild von fiasko
fiasko

Registriert seit: 10. Dez 2002
Ort: Dresden
506 Beiträge
 
#2

Re: Anwendung --> Dienst erstellen

  Alt 27. Okt 2004, 20:10
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:
procedure TWorkerThread.Execute(..);
begin
  while not Terminated do
  begin
    // hier immer einen Block abarbeiten
  end;
end;
Das starten vom Dienst aus sieht dann so aus:

myThread := TWorkerThread.Create(false); und zum beenden sollte das reichen:

Delphi-Quellcode:
if Assigned(myThread) then
begin
  myThread.Terminated;
  myThread.WaitFor;
  FreeAndNil(myThread);
end;
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.
Thomas Liske
Posts comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
  Mit Zitat antworten Zitat
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#3

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 08:29
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?

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:
if Assigned(myThread) then
begin
  myThread.Terminated;
  myThread.WaitFor;
  FreeAndNil(myThread);
end;
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?

Delphi-Quellcode:
procedure TimeManagerThread.Execute;
begin
  while not Terminated do
  begin
    FormCreate;
  end;
  FormCloseQuery;
  { Thread-Code hier einfügen }
end;
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.

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:
procedure TimeManagerThread.Execute;
begin
   FormCreate;
   if terminated then
      FormCloseQuery;
end;
und alles was ich in meinen Dienst reingepackt habe wie wie die oberen beiden Sachen, die meckert er an, wie
Undefinierter Bezeichner: 'TMThread'
Operator oder Semikolon fehlt
Susanne
  Mit Zitat antworten Zitat
Benutzerbild von fiasko
fiasko

Registriert seit: 10. Dez 2002
Ort: Dresden
506 Beiträge
 
#4

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 13:20
Hallo,

Zitat von Susanne:
In myThread.Execute packe ich dann die Funktion, die die ganze Abarbeitung der Blöcke steuert. Ist das richtig?
Korrekt. Der neue Thread wird dann parallel zum Rest deines Dientes/Programmes ausgeführt.


Zitat von Susanne:
und in die Unit des Dienstes in der Methode onStart kommt dann dieses rein, und dadurch wird der Thread dann gestartet?

myThread := TWorkerThread.Create(false);
Ja, der Parameter false gibt an das er sofort loslaufen soll. Das steht auch in der Hilfe zu Delphi-Referenz durchsuchenTThread. Außerdem kannst du dort noch solche Sachen machen wie Priorität des Threads festlegen (Eigenschaft Delphi-Referenz durchsuchenTThread.Priority), damit er den Rechner nicht so auslastet.

Zitat von Susanne:
Ich habe auch noch zwei Timer in der BlockVerarbeitung mit drin, muss ich da noch was besonderes beachten?

...
Wieso hast du denn da noch ein Form drinne? Es ist ein Dienst und die haben so etwas eigentlich nicht! Hast du da irgend etwas anderes wichtiges drauf außer die Timer?

Zitat von Susanne:
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?
Nicht ganz, das Assigned ist nur dazu da um zu schauen ob der Thread auch schon gestarten oder nicht schon beendet wurde. Das myThread.Terminate sorgt dafür das im Thread u.a. das Terminated wahr wird. Durch das myThread.WaitFor wartet die onStop Methode bis der Thread auch wirklich fertig ist und das FreeAndNil gibt dann einfach den Thread frei.

Zitat von Susanne:
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.
Wie gesagt - Dienste haben keine Formulare! Wenn der Benutzer etwas rumklicken können muß (außer zum Beenden) ist ein Dienst dafür vielleicht nicht geeignet.
Thomas Liske
Posts comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
  Mit Zitat antworten Zitat
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#5

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 13:37
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.
Susanne
  Mit Zitat antworten Zitat
Benutzerbild von fiasko
fiasko

Registriert seit: 10. Dez 2002
Ort: Dresden
506 Beiträge
 
#6

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 13:42
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.
Thomas Liske
Posts comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
  Mit Zitat antworten Zitat
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#7

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 15:36
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.
Susanne
  Mit Zitat antworten Zitat
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#8

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 21:53
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:
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.
Damit bin ich mir erst mal sicher, dass der Thread läuft. Nun habe ich das ganze nochmal mit dem Dienst probiert.

Delphi-Quellcode:
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.
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

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?
Susanne
  Mit Zitat antworten Zitat
Benutzerbild von fiasko
fiasko

Registriert seit: 10. Dez 2002
Ort: Dresden
506 Beiträge
 
#9

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 22:01
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!
Thomas Liske
Posts comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
  Mit Zitat antworten Zitat
Susanne

Registriert seit: 21. Mai 2004
Ort: Lage
232 Beiträge
 
Delphi 2005 Professional
 
#10

Re: Anwendung --> Dienst erstellen

  Alt 28. Okt 2004, 22:08
Es soll kein Formular geöffnet werden, einfach irgendein Programm, z.B. Word. Geht das auch nicht?
Susanne
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:08 Uhr.
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