Écriture de la fonction main d’un programme de service

La fonction main d’un programme de service appelle la fonction StartServiceCtrlDispatcher pour se connecter au gestionnaire de contrôle de service (SCM) et démarrer le thread de répartiteur de contrôle. Le thread de répartiteur boucle, en attendant les demandes de contrôle entrantes pour les services spécifiés dans la table de répartition. Ce thread retourne en cas d’erreur ou lorsque tous les services du processus se sont arrêtés. Lorsque tous les services du processus se sont arrêtés, le SCM envoie une demande de contrôle au thread de répartiteur lui demandant de se quitter. Ce thread retourne ensuite à partir de l’appel StartServiceCtrlDispatcher et le processus peut se terminer.

Les définitions globales suivantes sont utilisées dans cet exemple.

#define SVCNAME TEXT("SvcName")

SERVICE_STATUS          gSvcStatus; 
SERVICE_STATUS_HANDLE   gSvcStatusHandle; 
HANDLE                  ghSvcStopEvent = NULL;

L’exemple suivant peut être utilisé comme point d’entrée pour un programme de service qui prend en charge un seul service. Si votre programme de service prend en charge plusieurs services, ajoutez les noms des services supplémentaires à la table de répartition afin qu’ils puissent être surveillés par le thread de répartiteur.

La fonction _tmain est le point d’entrée. La fonction SvcReportEvent écrit des messages d’information et des erreurs dans le journal des événements. Pour plus d’informations sur l’écriture de la fonction SvcMain, consultez Écriture d’une fonction ServiceMain. Pour plus d’informations sur la fonction SvcInstall, consultez Installation d’un service. Pour plus d’informations sur l’écriture de la fonction SvcCtrlHandler, consultez Écriture d’une fonction de gestionnaire de contrôle. Pour obtenir l’exemple de service complet, y compris la source de la fonction SvcReportEvent, consultez Svc.cpp.

//
// Purpose: 
//   Entry point for the process
//
// Parameters:
//   None
// 
// Return value:
//   None, defaults to 0 (zero)
//
int __cdecl _tmain(int argc, TCHAR *argv[])
{ 
    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if( lstrcmpi( argv[1], TEXT("install")) == 0 )
    {
        SvcInstall();
        return;
    }

    // TO_DO: Add any additional services for the process to this table.
    SERVICE_TABLE_ENTRY DispatchTable[] = 
    { 
        { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, 
        { NULL, NULL } 
    }; 
 
    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.

    if (!StartServiceCtrlDispatcher( DispatchTable )) 
    { 
        SvcReportEvent(TEXT("StartServiceCtrlDispatcher")); 
    } 
} 

Voici un exemple Sample.h généré par le compilateur de messages. Pour plus d’informations, consultez Sample.mc.

 // The following are message definitions.
//
//  Values are 32 bit values layed out as follows:
//
//   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
//   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
//  +---+-+-+-----------------------+-------------------------------+
//  |Sev|C|R|     Facility          |               Code            |
//  +---+-+-+-----------------------+-------------------------------+
//
//  where
//
//      Sev - is the severity code
//
//          00 - Success
//          01 - Informational
//          10 - Warning
//          11 - Error
//
//      C - is the Customer code flag
//
//      R - is a reserved bit
//
//      Facility - is the facility code
//
//      Code - is the facility's status code
//
//
// Define the facility codes
//
#define FACILITY_SYSTEM                  0x0
#define FACILITY_STUBS                   0x3
#define FACILITY_RUNTIME                 0x2
#define FACILITY_IO_ERROR_CODE           0x4


//
// Define the severity codes
//
#define STATUS_SEVERITY_WARNING          0x2
#define STATUS_SEVERITY_SUCCESS          0x0
#define STATUS_SEVERITY_INFORMATIONAL    0x1
#define STATUS_SEVERITY_ERROR            0x3


//
// MessageId: SVC_ERROR
//
// MessageText:
//
//  An error has occurred (%2).
//  
//
#define SVC_ERROR                        ((DWORD)0xC0020001L)

Point d’entrée de service

Exemple de service complet