Condividi tramite


Funzione ServiceMain

Quando un programma di controllo del servizio richiede l'esecuzione di un nuovo servizio, Gestione controllo servizi avvia il servizio e invia una richiesta di avvio al dispatcher del controllo. Il dispatcher di controllo crea un nuovo thread per eseguire la funzione diservicemainper il servizio. Per un esempio, vedere Scrittura di una funzione ServiceMain.

La funzioneServiceMain deve eseguire le attività seguenti:

  1. Inizializzare tutte le variabili globali.

  2. Chiamare immediatamente la funzioneRegisterServiceCtrlHandlerper registrare una funzionegestoreper gestire le richieste di controllo per il servizio. Il valore restituito di RegisterServiceCtrlHandler è un handle di stato del servizio che verrà usato nelle chiamate per notificare allo stato del servizio SCM.

  3. Eseguire l'inizializzazione. Se si prevede che il tempo di esecuzione del codice di inizializzazione sia molto breve (inferiore a un secondo), l'inizializzazione può essere eseguita direttamente in ServiceMain.

    Se si prevede che il tempo di inizializzazione sia superiore a un secondo, il servizio deve usare una delle tecniche di inizializzazione seguenti:

    • Chiamare la funzioneSetServiceStatusper segnalare SERVICE_RUNNING ma non accettare controlli fino al termine dell'inizializzazione. Il servizio esegue questa operazione chiamando SetServiceStatus con dwCurrentState impostato su SERVICE_RUNNING e dwControlsAccepted impostato su 0 nella struttura SERVICE_STATUS. In questo modo, SCM non invierà alcuna richiesta di controllo al servizio prima che sia pronta e libera gestione controllo per gestire altri servizi. Questo approccio all'inizializzazione è consigliato per le prestazioni, in particolare per i servizi di avvio automatico.

    • Report SERVICE_START_PENDING, accettare nessun controllo e specificare un hint di attesa. Se il codice di inizializzazione del servizio esegue attività che richiedono più tempo del valore dell'hint di attesa iniziale, il codice deve chiamare periodicamente la funzione SetServiceStatus (possibilmente con un hint di attesa modificato) per indicare che è in corso l'avanzamento. Assicurarsi di chiamare SetServiceStatus solo se l'inizializzazione è in corso. In caso contrario, SCM può attendere che il servizio entri nello stato SERVICE_RUNNING presupponendo che il servizio stia effettuando progressi e impedisca l'avvio di altri servizi. Non chiamare SetServiceStatus da un thread separato, a meno che non si sia certi che il thread che esegue l'inizializzazione sia effettivamente in corso.

      Un servizio che usa questo approccio può anche specificare un valore check-point e incrementare periodicamente il valore durante un'inizializzazione lunga. Il programma che ha avviato il servizio può chiamare QueryServiceStatus o QueryServiceStatusEx per ottenere il valore del punto di controllo più recente da Gestione controllo software e usare il valore per segnalare lo stato di avanzamento incrementale all'utente.

  4. Al termine dell'inizializzazione, chiamare SetServiceStatus per impostare lo stato del servizio su SERVICE_RUNNING e specificare i controlli che il servizio è pronto ad accettare. Per un elenco dei controlli, vedere la struttura SERVICE_STATUS.

  5. Eseguire le attività del servizio o, se non sono presenti attività in sospeso, restituire il controllo al chiamante. Qualsiasi modifica nello stato del servizio garantisce una chiamata a SetServiceStatus per segnalare nuove informazioni sullo stato.

  6. Se si verifica un errore durante l'inizializzazione o l'esecuzione del servizio, il servizio deve chiamare SetServiceStatus per impostare lo stato del servizio su SERVICE_STOP_PENDING se la pulizia sarà lunga. Al termine della pulizia, chiamare SetServiceStatus per impostare lo stato del servizio su SERVICE_STOPPED dall'ultimo thread da terminare. Assicurarsi di impostare il dwServiceSpecificExitCode e dwWin32ExitCode membri della struttura SERVICE_STATUS per identificare l'errore.

scrittura di una funzione ServiceMain