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 Array lpServiceArgVectors .

[in] lpServiceArgVectors

Die null-beendeten Argumentzeichenfolgen, die durch den 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 allen zusätzlichen Argumenten (lpServiceArgVectors[1] bis lpServiceArgVectors[dwNumServicesArgs-1]).

Wenn der Benutzer einen manuellen Dienst mit dem Snap-In Dienste aus dem Systemsteuerung startet, stammen die Zeichenfolgen für den lpServiceArgVectors-Parameter aus dem Eigenschaftendialogfeld für den Dienst (klicken Sie im Snap-In Dienste mit der rechten Maustaste auf den Diensteintrag, klicken Sie auf Eigenschaften, und geben Sie die Parameter in Startparameter ein.)

Rückgabewert

Keine

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 Standard Thread des Dienstprozesses ruft die Funktion StartServiceCtrlDispatcher mit einem Zeiger auf ein Array von SERVICE_TABLE_ENTRY Strukturen auf. Anschließend sendet der Dienststeuerungs-Manager eine Startanforderung an den Dienststeuerungsverteiler 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 Funktion RegisterServiceCtrlHandlerEx aufrufen, um eine HandlerEx-Funktion zum Verarbeiten von Steuerelementanforderungen anzugeben. Als Nächstes sollte die SetServiceStatus-Funktion aufgerufen werden, um status Informationen 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 (SCM) wartet, bis der Dienst eine status von SERVICE_RUNNING meldet. Es wird empfohlen, dass der Dienst diese 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.

Der SCM sperrt die Datenbank für die Dienststeuerung 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 die Ausführung eines anderen Diensts erforderlich ist, 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 er eine status von SERVICE_RUNNING meldet.

Die ServiceMain-Funktion sollte ein globales Ereignis erstellen, die Funktion RegisterWaitForSingleObject für dieses Ereignis aufrufen und beenden. Dadurch wird der Thread beendet, in dem die ServiceMain-Funktion ausgeführt wird, der Dienst wird jedoch 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 Funktion "Warterückruf" aus. Diese Funktion sollte sauber Aufgaben ausführen, einschließlich des Schließens des globalen Ereignisses, und SetServiceStatus mit SERVICE_STOPPED aufrufen. 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 ist, wenn mehrere Dienste einen Prozess gemeinsam nutzen.

Beispiele

Ein Beispiel finden Sie unter Schreiben einer ServiceMain-Funktion.

Hinweis

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 nicht codierungsneutralem Code 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
Unterstützte Mindestversion (Client) Windows XP [nur Desktop-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [nur Desktop-Apps]
Zielplattform Windows
Kopfzeile winsvc.h (einschließen von Windows.h)

Weitere Informationen

HandlerEx

RegisterServiceCtrlHandlerEx

Registerwaitforsingleobject

SERVICE_TABLE_ENTRY

Dienstfunktionen

Service ServiceMain-Funktion

SetServiceStatus

StartServiceCtrlDispatcher