LPSERVICE_MAIN_FUNCTIONA Rückruffunktion (winsvc.h)
Der Einstiegspunkt für einen Dienst.
Der LPSERVICE_MAIN_FUNCTION Typ definiert einen Zeiger auf diese Rückruffunktion. ServiceMain- ist ein Platzhalter für einen anwendungsdefinierten Funktionsnamen.
Syntax
LPSERVICE_MAIN_FUNCTIONA LpserviceMainFunctiona;
void LpserviceMainFunctiona(
[in] DWORD dwNumServicesArgs,
[in] LPSTR *lpServiceArgVectors
)
{...}
Parameter
[in] dwNumServicesArgs
Die Anzahl der Argumente im lpServiceArgVectors Array.
[in] lpServiceArgVectors
Die Zeichenfolgen, die vom Aufruf der StartService--Funktion, die den Dienst gestartet hat, an den Dienst übergeben werden. Wenn keine Argumente vorhanden sind, kann dieser Parameter NULL sein. Andernfalls ist das erste Argument (lpServiceArgVectors[0]) der Name des Diensts, gefolgt von zusätzlichen Argumenten (lpServiceArgVectors[1] bis lpServiceArgVectors[dwNumServicesArgs-1]).
Wenn der Benutzer einen manuellen Dienst mithilfe des Services-Snap-Ins über die Systemsteuerung startet, werden die Zeichenfolgen für die lpServiceArgVectors Parameter aus dem Eigenschaftendialogfeld für den Dienst stammen (klicken Sie im Dienst-Snap-In mit der rechten Maustaste auf den Diensteintrag, klicken Sie auf Eigenschaften, und geben Sie die Parameter in Startparameterein.)
Rückgabewert
Nichts
Bemerkungen
Ein Dienstprogramm kann einen oder mehrere Dienste starten. Ein Dienstprozess verfügt über eine SERVICE_TABLE_ENTRY Struktur für jeden Dienst, den er starten kann. Die Struktur gibt den Dienstnamen und einen Zeiger auf die ServiceMain--Funktion für diesen Dienst an.
Wenn der Dienststeuerungs-Manager eine Anforderung zum Starten eines Diensts empfängt, startet er den Dienstprozess (sofern er noch nicht ausgeführt wird). Der Hauptthread des Dienstprozesses ruft die StartServiceCtrlDispatcher Funktion mit einem Zeiger auf ein Array von SERVICE_TABLE_ENTRY Strukturen auf. Anschließend sendet der Dienststeuerungs-Manager eine Startanforderung an den Dienststeuerungs-Dispatcher für diesen Dienstprozess. Der Dienststeuerungsverteiler erstellt einen neuen Thread, um die ServiceMain Funktion des gestarteten Diensts auszuführen.
Die ServiceMain--Funktion sollte sofort die RegisterServiceCtrlHandlerEx--Funktion aufrufen, um eine HandlerEx--Funktion zum Behandeln von Steuerelementanforderungen anzugeben. Als Nächstes sollte die SetServiceStatus--Funktion aufgerufen werden, um Statusinformationen an den Dienststeuerungs-Manager zu senden. Nach diesen Aufrufen sollte die Funktion die Initialisierung des Diensts abschließen. Versuchen Sie nicht, einen anderen Dienst in der ServiceMain--Funktion zu starten.
Der Dienststeuerungs-Manager (Service Control Manager, SCM) wartet, bis der Dienst einen Status von SERVICE_RUNNING meldet. Es wird empfohlen, dass der Dienst diesen Status so schnell wie möglich meldet, da andere Komponenten im System, die eine Interaktion mit SCM erfordern, während dieser Zeit blockiert werden. Einige Funktionen erfordern möglicherweise eine direkte oder indirekte Interaktion mit dem SCM.
Das SCM sperrt die Dienststeuerungsdatenbank während der Initialisierung. Wenn ein Dienst also versucht, StartService- während der Initialisierung aufzurufen, wird der Aufruf blockiert. Wenn der Dienst dem SCM meldet, dass er erfolgreich gestartet wurde, kann er StartService-aufrufen. Wenn für den Dienst ein anderer Dienst ausgeführt werden muss, sollte der Dienst die erforderlichen Abhängigkeiten festlegen.
Darüber hinaus sollten Sie während der Dienstinitialisierung keine Systemfunktionen aufrufen. Der Dienstcode sollte Systemfunktionen erst aufrufen, nachdem der Status SERVICE_RUNNING gemeldet wurde.
Die ServiceMain--Funktion sollte ein globales Ereignis erstellen, das RegisterWaitForSingleObject--Funktion für dieses Ereignis aufrufen und beenden. Dadurch wird der Thread beendet, der die ServiceMain--Funktion ausführt, aber den Dienst nicht beendet. Wenn der Dienst beendet wird, sollte der Dienststeuerungshandler SetServiceStatus- mit SERVICE_STOP_PENDING aufrufen und dieses Ereignis signalisieren. Ein Thread aus dem Threadpool führt die Warterückruffunktion aus; Diese Funktion sollte Bereinigungsaufgaben ausführen, einschließlich des Schließens des globalen Ereignisses und aufrufen SetServiceStatus- mit SERVICE_STOPPED. Nachdem der Dienst beendet wurde, sollten Sie keinen zusätzlichen Dienstcode ausführen, da Sie eine Racebedingung einführen können, wenn der Dienst eine Startsteuerung empfängt und ServiceMain- erneut aufgerufen wird. Beachten Sie, dass dieses Problem wahrscheinlicher auftritt, wenn mehrere Dienste einen Prozess gemeinsam nutzen.
Beispiele
Ein Beispiel finden Sie unter Schreiben einer ServiceMain-Funktion.
Anmerkung
Der winsvc.h-Header definiert LPSERVICE_MAIN_FUNCTION als Alias, der die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante automatisch auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit Code, der nicht codierungsneutral ist, kann zu Nichtübereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.
Anforderungen
Anforderung | Wert |
---|---|
mindestens unterstützte Client- | Windows XP [nur Desktop-Apps] |
mindestens unterstützte Server- | Windows Server 2003 [Nur Desktop-Apps] |
Zielplattform- | Fenster |
Header- | winsvc.h (enthalten Windows.h) |