LPSERVICE_MAIN_FUNCTIONW 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_FUNCTIONW LpserviceMainFunctionw;
void LpserviceMainFunctionw(
[in] DWORD dwNumServicesArgs,
[in] LPWSTR *lpServiceArgVectors
)
{...}
Paramètres
[in] dwNumServicesArgs
Nombre d’arguments dans le tableau lpServiceArgVectors.
[in] lpServiceArgVectors
Chaînes d’arguments terminées par null passées au service par l’appel à la fonction StartService qui a démarré le service. S’il n’existe aucun argument, ce paramètre peut être NULL. Sinon, le premier argument (lpServiceArgVectors[0]) est le nom du service, suivi de tous les 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 lpServiceArgVector s proviennent de la boîte de dialogue propriétés du service (à partir du composant logiciel enfichable Services, cliquez avec le bouton droit sur l’entrée de service, cliquez sur Propriétés, puis entrez les paramètres dans Paramètres de démarrage.)
Valeur de retour
Aucun
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 principal 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 démarré.
La fonction ServiceMain
Le Gestionnaire de contrôle de service (SCM) attend que le service signale un état de SERVICE_RUNNING. Il est recommandé que le service signale cet état le plus rapidement possible, car d’autres composants du système qui nécessitent une interaction avec SCM seront bloqués pendant ce temps. Certaines fonctions peuvent nécessiter une interaction avec le SCM directement ou indirectement.
Le SCM verrouille la base de données de contrôle de service lors de l’initialisation. Par conséquent, si un service tente d’appeler StartService lors de l’initialisation, l’appel se bloque. 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, le service 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 doit appeler les fonctions système uniquement une fois qu’il signale un état 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 n’arrête pas le 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 de nettoyage, 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 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.
Note
L’en-tête winsvc.h définit LPSERVICE_MAIN_FUNCTION en tant qu’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.
Exigences
Exigence | Valeur |
---|---|
client minimum pris en charge | Windows XP [applications de bureau uniquement] |
serveur minimum pris en charge | Windows Server 2003 [applications de bureau uniquement] |
plateforme cible | Windows |
d’en-tête | winsvc.h (inclure Windows.h) |