Delen via


ServiceMain, functie

Wanneer een servicebeheerprogramma aanvraagt dat een nieuwe service wordt uitgevoerd, wordt de service door Service Control Manager (SCM) gestart en wordt er een startaanvraag naar de verzender van het besturingselement verzonden. De control dispatcher maakt een nieuwe thread voor het uitvoeren van de ServiceMain-functie voor de service. Zie bijvoorbeeld Een ServiceMain-functie schrijven.

De functie ServiceMain moet de volgende taken uitvoeren:

  1. Initialiseer alle globale variabelen.

  2. Roep de functie RegisterServiceCtrlHandler onmiddellijk aan om een Handler--functie te registreren om controleaanvragen voor de service te verwerken. De retourwaarde van RegisterServiceCtrlHandler- is een servicestatushandler die wordt gebruikt in aanroepen om de SCM op de hoogte te stellen van de servicestatus.

  3. Initialisatie uitvoeren. Als de uitvoeringstijd van de initialisatiecode naar verwachting zeer kort is (minder dan één seconde), kan initialisatie rechtstreeks in ServiceMainworden uitgevoerd.

    Als de initialisatietijd naar verwachting langer is dan één seconde, moet de service een van de volgende initialisatietechnieken gebruiken:

    • Roep de functie SetServiceStatus aan om SERVICE_RUNNING te rapporteren, maar accepteer geen besturingselementen totdat de initialisatie is voltooid. De service doet dit door SetServiceStatus- aan te roepen met dwCurrentState- ingesteld op SERVICE_RUNNING en dwControlsAccepted ingesteld op 0 in de SERVICE_STATUS structuur. Dit zorgt ervoor dat de SCM geen controleaanvragen naar de service verzendt voordat deze gereed is en de SCM vrij maakt om andere services te beheren. Deze benadering voor initialisatie wordt aanbevolen voor prestaties, met name voor autostartservices.

    • Rapport SERVICE_START_PENDING, accepteer geen besturingselementen en geef een wachthint op. Als de initialisatiecode van uw service taken uitvoert die naar verwachting langer duren dan de waarde van de eerste wachthint, moet uw code de SetServiceStatus-functie periodiek aanroepen (mogelijk met een herziene wachthint) om aan te geven dat er vooruitgang wordt geboekt. Zorg ervoor dat u SetServiceStatus alleen aanroept als de initialisatie voortgang maakt. Anders kan de SCM wachten totdat uw service de status SERVICE_RUNNING heeft ingevoerd, ervan uitgaande dat uw service voortgang maakt en verhindert dat andere services worden gestart. Roep SetServiceStatus niet aan vanuit een afzonderlijke thread, tenzij u zeker weet dat de thread die de initialisatie uitvoert, daadwerkelijk voortgang maakt.

      Een service die deze methode gebruikt, kan ook een controlepuntwaarde opgeven en de waarde periodiek verhogen tijdens een lange initialisatie. Het programma dat de service heeft gestart, kan QueryServiceStatus of QueryServiceStatusEx aanroepen om de meest recente controlepuntwaarde van de SCM te verkrijgen en de waarde te gebruiken om incrementele voortgang aan de gebruiker te rapporteren.

  4. Wanneer de initialisatie is voltooid, roept u SetServiceStatus- aan om de servicestatus in te stellen op SERVICE_RUNNING en geeft u de besturingselementen op die door de service worden geaccepteerd. Zie de SERVICE_STATUS structuur voor een lijst met besturingselementen.

  5. Voer de servicetaken uit of, als er geen taken in behandeling zijn, keert u het besturingselement terug naar de beller. Elke wijziging in de servicestatus garandeert een aanroep van SetServiceStatus om nieuwe statusgegevens te rapporteren.

  6. Als er een fout optreedt tijdens het initialiseren of uitvoeren van de service, moet de service SetServiceStatus- aanroepen om de servicestatus in te stellen op SERVICE_STOP_PENDING als het opschonen lang duurt. Nadat het opschonen is voltooid, roept u SetServiceStatus- aan om de servicestatus in te stellen op SERVICE_STOPPED vanaf de laatste thread die moet worden beëindigd. Zorg ervoor dat u de dwServiceSpecificExitCode- en dwWin32ExitCode leden van de SERVICE_STATUS-structuur instelt om de fout te identificeren.

een ServiceMain-functie schrijven