Schreiben eines Win2000-Dienstprogramms mit Delphi
Zusammenfassung: In diesem Artikel wird die Verwendung von Delphi zum Schreiben von Win2000-Dienstprogrammen vorgestellt. Die beteiligten Klassen sind TServiceApplicatoin, TService, TServiceThread usw.
Schlüsselwörter: Service/Service
1. Einführung in Win2000-Dienste
Die Dienstanwendung ist ein Hintergrundprogramm, das unter WinNT ausgeführt wird. Jede Dienstanwendung kann mehrere Dienste enthalten, und jeder Dienst ist einer der Threads (der Dienst kann auch mehrere Unterdienste-Threads erstellen). Durch die Verwendung von Diensten können Anwendungen spezielle Berechtigungen erhalten, und der Benutzer beendet das Programm nicht direkt über den Win2000-Task-Manager. Daher werden Dienste häufig zum Erreichen bestimmter besonderer Ziele verwendet.
Über das Dienstverwaltungstool in der Win2000-Systemsteuerung können wir die Eigenschaften des Dienstes festlegen/anzeigen:
(1) Dienstname; (3) Beschreibung; (5) Abhängigkeiten;
Unter anderem identifiziert der Dienstname den Dienst.
Nehmen Sie als Beispiel das Programm C:/WINNT/System32/services.exe von Win2000. Diese Exe-Datei entspricht einer Dienstanwendung und ist die sichtbare Entität des Dienstprogramms, das mehrere Dienste (Service) enthält. Dhcp (DHCP) Client), Messenger usw. Wenn wir einen Dienst beenden, werden andere Dienste in der Dienstanwendung, in der sich der Dienst befindet, nicht beendet.
In Delphi stellen uns Borland-Ingenieure TServiceApplication, TService, TServiceThread und andere Klassen zur Verfügung, die eine große Anzahl von Details kapseln und die Entwicklung von Serviceprogrammen vereinfachen.
2. TServiceApplication
In Delphi entspricht die Klasse TServiceApplication der oben genannten ServiceApplication. Mithilfe der Delphi-Entwicklungsumgebung erstellen wir ein neues Service Application PRoject und eine von TService geerbte Klasse. Das Anwendungsobjekt in der Projektdatei ist eine TServiceApplication-Instanz. Jede TServiceApplication enthält mehrere TService-Objekte, die genau der oben genannten quantitativen Beziehung zwischen Dienstprogrammen und Diensten entsprechen.
Durch Lesen der Definitionen der Klassen TServiceApplication und TService können wir erkennen, dass TServiceApplication von der Klasse TComponent erbt, TService von der Klasse TDataModule stammt und das Application-Objekt für das Erstellen und Zerstören jedes TService-Objekts verantwortlich ist. Verfolgen Sie den Code unten
Application.CreateForm(TService1, Service1);
Es kann festgestellt werden, dass die Eigentümer der erstellten TService-Objekte alle Anwendungsobjekte sind. In VCL FrameWork ist der Eigentümer immer für die Zerstörung jedes Komponentenobjekts verantwortlich (die TComponent-Klasse von VCL übernimmt den Composite-Modus), sodass TServiceApplication auch jedes TService-Objekt zerstört.
Wenn Sie dem Code von TServiceApplication.Run folgen, können Sie feststellen, dass TServiceApplication zunächst die laufenden Parameter analysiert und die Installation und Deinstallation des Dienstes implementiert. Initialisieren Sie dann ein ServiceStartTable-Array, das den Dienstnamen und den laufenden Eintrag jedes Dienstobjekts enthält. Erstellen Sie schließlich ein TServiceStartThread-Objekt, bei dem es sich um ein Thread-Objekt handelt, und rufen Sie die API StartServiceCtrlDispatcher vom Thread aus auf, um mehrere in der ServiceStartTable angegebene Dienste zu starten. Der ServiceApplication-Hauptthread durchläuft ständig Nachrichten und verarbeitet sie, z. B. den Empfang von Anforderungen zum Stoppen/Pausieren eines Dienstes.
3. TService
Die TService-Klasse erbt von der TDataModule-Klasse, was bedeutet, dass wir eine große Anzahl von VCL-Steuerelementen hinzufügen können, um umfangreiche Funktionen zu erreichen. Darüber hinaus können wir auch OnStart, OnPause, OnStop, OnContinue, OnCreate, OnShutDown und andere Ereignisse verarbeiten. Was erklärt werden muss, ist: OnStop bedeutet, dass der Dienst gestoppt wurde, und OnShutDown bedeutet, dass die ServiceApplication nicht mehr ausgeführt wird, was bedeutet, dass auch andere Dienste beendet wurden.
Wie bereits erwähnt, startet ServiceApplication jeden Dienst durch den Aufruf von StartServiceCtrlDispatcher. StartServiceCtrlDispatcher startet den Eingang von TService, nämlich TService.Main. TService.Main registriert zunächst den Dienst und ruft dann TService.DoStart auf. TService.DoStart erstellt ein internes TServiceThread-Mitgliedsobjekt, bei dem es sich um ein Thread-Objekt handelt. Wenn wir TService1.OnExecute verarbeiten, können wir feststellen, dass TService alle Anforderungen zur Verarbeitung an das TServiceThread-Mitgliedsobjekt delegiert Die Standardmethode verarbeitet alle Anfragen.
TService. ServiceExecute ist der Hauptinhalt von TService. Damit ein Dienst normal ausgeführt werden kann, muss er nicht nur die Ziele erfüllen, auf die er sich konzentrieren muss (z. B. einen bestimmten Port abhören, eine bestimmte Aufgabe ausführen usw.), sondern auch auf externe Befehle/Anfragen reagieren: z Beenden, Pausieren und Fortsetzen des Dienstes. Daher können Sie erwägen, einen dedizierten Thread zu erstellen, um diese Aufgabe abzuschließen und externe Befehle/Anfragen in ServiceExecute zu verarbeiten. Der Code lautet also wie folgt:
solange es nicht beendet ist, beginnt es
ServiceThread.ProcessRequests(False);
Ende;
Natürlich können Sie in OnExecute auch bestimmte Aufgaben erledigen, wie z. B. das Abhören eines bestimmten Ports, dies führt jedoch häufig dazu, dass der Dienst nicht rechtzeitig auf Stop/Pause und andere Anfragen reagieren kann. Wenn OnExecute abgeschlossen ist, hat der Dienst seine Aufgabe tatsächlich abgeschlossen und steht kurz vor dem Ende (Beenden).
Referenzen:
MSDN, Delphi VCL-Quellcode, Delphi-Hilfedokumentation