Share via


LPSERVICE_MAIN_FUNCTIONA fonction de rappel (winsvc.h)

Point d’entrée d’un service.

Le type LPSERVICE_MAIN_FUNCTION définit un pointeur vers cette fonction de rappel. ServiceMain est un espace réservé pour un nom de fonction défini par l’application.

Syntaxe

LPSERVICE_MAIN_FUNCTIONA LpserviceMainFunctiona;

void LpserviceMainFunctiona(
  [in] DWORD dwNumServicesArgs,
  [in] LPSTR *lpServiceArgVectors
)
{...}

Paramètres

[in] dwNumServicesArgs

Nombre d’arguments dans le tableau lpServiceArgVectors .

[in] lpServiceArgVectors

Chaînes d’arguments null transmises au service par l’appel à la fonction StartService qui a démarré le service. S’il n’y a pas d’arguments, ce paramètre peut avoir la valeur NULL. Dans le cas contraire, le premier argument (lpServiceArgVectors[0]) est le nom du service, suivi des arguments supplémentaires (lpServiceArgVectors[1] via lpServiceArgVectors[dwNumServicesArgs-1]).

Si l’utilisateur démarre un service manuel à l’aide du composant logiciel enfichable Services à partir du Panneau de configuration, les chaînes du paramètre lpServiceArgVectors proviennent de la boîte de dialogue propriétés du service (dans le composant logiciel enfichable Services, cliquez avec le bouton droit sur l’entrée du service, cliquez sur Propriétés, puis entrez les paramètres dans Paramètres de démarrage.)

Valeur de retour

None

Remarques

Un programme de service peut démarrer un ou plusieurs services. Un processus de service a une structure SERVICE_TABLE_ENTRY pour chaque service qu’il peut démarrer. La structure spécifie le nom du service et un pointeur vers la fonction ServiceMain pour ce service.

Lorsque le gestionnaire de contrôle de service reçoit une demande de démarrage d’un service, il démarre le processus de service (s’il n’est pas déjà en cours d’exécution). Le thread main du processus de service appelle la fonction StartServiceCtrlDispatcher avec un pointeur vers un tableau de structures SERVICE_TABLE_ENTRY. Ensuite, le gestionnaire de contrôle de service envoie une demande de démarrage au répartiteur de contrôle de service pour ce processus de service. Le répartiteur de contrôle de service crée un thread pour exécuter la fonction ServiceMain du service en cours de démarrage.

La fonction ServiceMain doit immédiatement appeler la fonction RegisterServiceCtrlHandlerEx pour spécifier une fonction HandlerEx pour gérer les demandes de contrôle. Ensuite, il doit appeler la fonction SetServiceStatus pour envoyer status informations au gestionnaire de contrôle de service. Après ces appels, la fonction doit terminer l’initialisation du service. N’essayez pas de démarrer un autre service dans la fonction ServiceMain .

Le Gestionnaire de contrôle de service (SCM) attend que le service signale un status de SERVICE_RUNNING. Il est recommandé que le service signale cette status aussi rapidement que possible, car les autres composants du système qui nécessitent une interaction avec SCM seront bloqués pendant cette période. Certaines fonctions peuvent nécessiter une interaction directe ou indirecte avec le SCM.

Le SCM verrouille la base de données de contrôle de service pendant l’initialisation. Par conséquent, si un service tente d’appeler StartService pendant l’initialisation, l’appel est bloqué. Lorsque le service signale au SCM qu’il a démarré avec succès, il peut appeler StartService. Si le service nécessite l’exécution d’un autre service, celui-ci doit définir les dépendances requises.

En outre, vous ne devez pas appeler de fonctions système pendant l’initialisation du service. Le code de service ne doit appeler les fonctions système qu’après avoir fait état d’une status de SERVICE_RUNNING.

La fonction ServiceMain doit créer un événement global, appeler la fonction RegisterWaitForSingleObject sur cet événement et quitter. Cela met fin au thread qui exécute la fonction ServiceMain , mais ne met pas fin au service. Lorsque le service s’arrête, le gestionnaire de contrôle de service doit appeler SetServiceStatus avec SERVICE_STOP_PENDING et signaler cet événement. Un thread du pool de threads exécute la fonction de rappel d’attente ; cette fonction doit effectuer des tâches propre, notamment la fermeture de l’événement global, et appeler SetServiceStatus avec SERVICE_STOPPED. Une fois le service arrêté, vous ne devez pas exécuter de code de service supplémentaire, car vous pouvez introduire une condition de concurrence si le service reçoit un contrôle de démarrage et que ServiceMain est appelé à nouveau. Notez que ce problème est plus susceptible de se produire lorsque plusieurs services partagent un processus.

Exemples

Pour obtenir un exemple, consultez Écriture d’une fonction ServiceMain.

Notes

L’en-tête winsvc.h définit LPSERVICE_MAIN_FUNCTION comme un alias qui sélectionne automatiquement la version ANSI ou Unicode de cette fonction en fonction de la définition de la constante de préprocesseur UNICODE. Le mélange de l’utilisation de l’alias neutre en encodage avec du code qui n’est pas neutre en encodage peut entraîner des incompatibilités qui entraînent des erreurs de compilation ou d’exécution. Pour plus d’informations, consultez Conventions pour les prototypes de fonction.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows XP [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau uniquement]
Plateforme cible Windows
En-tête winsvc.h (inclure Windows.h)

Voir aussi

HandlerEx

RegisterServiceCtrlHandlerEx

RegisterWaitForSingleObject

SERVICE_TABLE_ENTRY

Fonctions de service

ServiceMain, fonction

SetServiceStatus

StartServiceCtrlDispatcher