Delen via


Service Control Handler, functie

Elke service heeft een besturingshandler, de Handler--functie, die wordt aangeroepen door de dispatcher voor besturingselementen wanneer het serviceproces een controleaanvraag ontvangt van een servicebeheerprogramma. Deze functie wordt daarom uitgevoerd in de context van de besturingszender. Zie Een besturingshandlerfunctie schrijvenvoor een voorbeeld.

Een service roept de RegisterServiceCtrlHandler- of RegisterServiceCtrlHandlerEx- functie aan om de handlerfunctie voor servicebeheer te registreren.

Wanneer de handler voor servicebeheer wordt aangeroepen, moet de service de functie SetServiceStatus aanroepen om de status alleen aan de SCM te rapporteren als het verwerken van de besturingscode ervoor zorgt dat de servicestatus wordt gewijzigd. Als het afhandelen van de besturingscode niet tot gevolg heeft dat de servicestatus wordt gewijzigd, is het niet nodig om SetServiceStatusaan te roepen.

Een servicebeheerprogramma kan besturingsaanvragen verzenden met behulp van de functie ControlService. Alle services moeten de SERVICE_CONTROL_INTERROGATE besturingscode accepteren en verwerken. U kunt acceptatie van de andere besturingscodes in- of uitschakelen door SetServiceStatusaan te roepen. Als u de SERVICE_CONTROL_DEVICEEVENT-besturingscode wilt ontvangen, moet u de functie RegisterDeviceNotification aanroepen. Services kunnen ook aanvullende door de gebruiker gedefinieerde besturingscodes verwerken.

Als een service de SERVICE_CONTROL_STOP besturingscode accepteert, moet deze stoppen bij ontvangst, naar de status SERVICE_STOP_PENDING of SERVICE_STOPPED. Nadat de SCM deze besturingscode heeft verzonden, worden er geen andere besturingscodes verzonden.

Windows XP: Als de service NO_ERROR retourneert en blijft worden uitgevoerd, blijft deze besturingscodes ontvangen. Dit gedrag is gewijzigd vanaf Windows Server 2003 en Windows XP met Service Pack 2 (SP2).

De besturingshandler moet binnen 30 seconden worden geretourneerd of de SCM retourneert een fout. Als een service langdurige verwerking moet uitvoeren wanneer de service de besturingshandler uitvoert, moet er een secundaire thread worden gemaakt om de langdurige verwerking uit te voeren en vervolgens terug te keren van de besturingshandler. Hierdoor voorkomt u dat de service de controle-dispatcher koppelt. Wanneer u bijvoorbeeld de stopaanvraag voor een service verwerkt die lang duurt, maakt u een andere thread om het stopproces af te handelen. De besturingshandler moet gewoon SetServiceStatus aanroepen met het SERVICE_STOP_PENDING bericht en teruggaan.

Wanneer de gebruiker het systeem afsluit, ontvangen alle besturingshandlers die SetServiceStatus hebben aangeroepen met de SERVICE_ACCEPT_PRESHUTDOWN besturingscode de SERVICE_CONTROL_PRESHUTDOWN besturingscode. De servicebeheerbeheerder wacht totdat de service stopt of de opgegeven time-outwaarde voor preshutdown verloopt (deze waarde kan worden ingesteld met de ChangeServiceConfig2-functie). Deze controlecode mag alleen in speciale omstandigheden worden gebruikt, omdat een service die deze melding afhandelt het afsluiten van het systeem blokkeert totdat de service stopt of het time-outinterval van preshutdown verloopt.

Nadat de preshutdown-meldingen zijn voltooid, ontvangen alle besturingshandlers die SetServiceStatus- hebben aangeroepen met de SERVICE_ACCEPT_SHUTDOWN besturingscode de SERVICE_CONTROL_SHUTDOWN besturingscode. Ze worden op de hoogte gesteld in de volgorde waarin ze worden weergegeven in de database met geïnstalleerde services. Een service heeft standaard ongeveer 20 seconden om opschoontaken uit te voeren voordat het systeem wordt afgesloten. Nadat deze tijd is verlopen, gaat het systeem afsluiten, ongeacht of het afsluiten van de service is voltooid. Houd er rekening mee dat als het systeem in de afsluitstatus blijft (niet opnieuw opgestart of uitgeschakeld), de service blijft worden uitgevoerd.

Als de service meer tijd nodig heeft om op te ruimen, worden er STOP_PENDING statusberichten verzonden, samen met een wachthint, zodat de servicecontroller weet hoe lang moet worden gewacht voordat wordt gerapporteerd aan het systeem dat het afsluiten van de service is voltooid. Als u echter wilt voorkomen dat een service stopt met afsluiten, is er een limiet voor hoe lang de servicecontroller wacht. Als de service wordt afgesloten via de module Services, is de limiet 125 seconden of 125.000 milliseconden. Als het besturingssysteem opnieuw wordt opgestart, wordt de tijdslimiet opgegeven in de WaitToKillServiceTimeout waarde (in milliseconden) van de volgende registersleutel:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

Belangrijk

Een service mag niet proberen de tijdslimiet te verhogen door deze waarde te wijzigen. Als u WaitToKillServiceTimeout handmatig moet instellen, moet de waarde in milliseconden staan.

Klanten moeten het besturingssysteem snel afsluiten. Als een computer met UPS-stroom bijvoorbeeld niet kan worden afgesloten voordat de UPS geen stroom meer heeft, kunnen gegevens verloren gaan. Daarom moeten services hun opschoontaken zo snel mogelijk voltooien. Het is een goede gewoonte om niet-opgeslagen gegevens te minimaliseren door regelmatig gegevens op te slaan, de gegevens bij te houden die op schijf worden opgeslagen en alleen uw niet-opgeslagen gegevens bij het afsluiten op te slaan. Omdat de computer wordt afgesloten, hoeft u geen tijd te besteden aan het vrijgeven van toegewezen geheugen of andere systeembronnen. Als u een server moet melden dat u afsluit, minimaliseert u de tijd die u wacht op een antwoord, omdat netwerkproblemen het afsluiten van uw service kunnen vertragen.

Houd er rekening mee dat tijdens het afsluiten van de service de SCM standaard geen rekening houdt met afhankelijkheden. De SCM inventariseert de lijst met actieve services en verzendt de opdracht SERVICE_CONTROL_SHUTDOWN. Daarom kan een service mislukken omdat een andere service waarvoor deze afhankelijk is, al is gestopt.

Als u de afsluitvolgorde van services handmatig wilt instellen, maakt u een registerwaarde met meerdere tekenreeksen met de servicenamen in de volgorde waarin ze moeten worden afgesloten en wijst u deze als volgt toe aan de PreshutdownOrder waarde van de Control-sleutel:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PreshutdownOrder="Shutdown Order

Als u de afsluitvolgorde van afhankelijke services van uw toepassing wilt instellen, gebruikt u de functie SetProcessShutdownParameters. De SCM gebruikt deze functie om de handler 0x1E0 prioriteit te geven. De SCM verzendt SERVICE_CONTROL_SHUTDOWN meldingen wanneer de besturingshandler wordt aangeroepen en wacht totdat de services worden afgesloten voordat ze van de besturingshandler terugkeren.

een besturingshandlerfunctie schrijven