Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Każda usługa ma program obsługi sterowania, funkcję obsługi, która jest wywoływana przez dyspozytor sterowania, gdy proces usługi odbiera żądanie sterowania z programu kontroli. W związku z tym ta funkcja jest wykonywana w kontekście dyspozytora sterującego. Aby zapoznać się z przykładem, zobacz Pisanie funkcji obsługi kontrolek.
Usługa wywołuje funkcję RegisterServiceCtrlHandler lub RegisterServiceCtrlHandlerEx, aby zarejestrować funkcję obsługi sterowania usługą.
Po wywołaniu programu obsługi kontrolki usługi usługa musi wywołać funkcję SetServiceStatus, aby zgłosić jej stan do SCM tylko wtedy, gdy obsługa kodu sterującego powoduje zmianę stanu usługi. Jeśli obsługa kodu kontrolnego nie powoduje zmiany stanu usługi, nie jest konieczne wywołanie SetServiceStatus.
Program kontroli usługi może wysyłać żądania sterowania przy użyciu funkcjiControlService. Wszystkie usługi muszą akceptować i przetwarzać kod kontroli SERVICE_CONTROL_INTERROGATE. Możesz włączyć lub wyłączyć akceptację innych kodów sterujących, wywołując SetServiceStatus. Aby otrzymać kod kontrolny SERVICE_CONTROL_DEVICEEVENT, należy wywołać funkcję RegisterDeviceNotification. Usługi mogą również obsługiwać dodatkowe kody kontrolek zdefiniowane przez użytkownika.
Jeśli usługa akceptuje kod kontrolny SERVICE_CONTROL_STOP, musi zatrzymać się po otrzymaniu, przechodząc do stanu SERVICE_STOP_PENDING lub SERVICE_STOPPED. Po wysłaniu tego kodu kontrolnego przez program SCM nie będzie wysyłać innych kodów kontrolnych.
Windows XP: Jeśli usługa zwraca NO_ERROR i nadal działa, nadal otrzymuje kody kontrolne. To zachowanie zmieniło się od systemu Windows Server 2003 i Windows XP z dodatkiem Service Pack 2 (SP2).
Procedura obsługi kontrolek musi zwrócić wartość w ciągu 30 sekund lub program SCM zwraca błąd. Jeśli usługa musi wykonywać długotrwałe przetwarzanie, gdy usługa wykonuje procedurę obsługi kontrolek, powinna utworzyć wątek pomocniczy, aby wykonać długotrwałe przetwarzanie, a następnie wrócić z programu obsługi kontrolek. Uniemożliwia to usłudze wiązanie dyspozytora kontrolnego. Na przykład w przypadku obsługi żądania zatrzymania dla usługi, która zajmuje dużo czasu, utwórz kolejny wątek do obsługi procesu zatrzymania. Procedura obsługi sterowania powinna po prostu wywołać SetServiceStatus z komunikatem SERVICE_STOP_PENDING i zwrócić.
Gdy użytkownik zamknie system, wszystkie programy obsługi sterowania, które wywołały SetServiceStatus za pomocą kodu sterowania SERVICE_ACCEPT_PRESHUTDOWN, otrzymają kod kontrolny SERVICE_CONTROL_PRESHUTDOWN. Menedżer kontroli usług czeka, aż usługa zostanie zatrzymana lub określona wartość limitu czasu przedterminowego wygaśnie (tę wartość można ustawić za pomocą funkcji ChangeServiceConfig2). Ten kod kontrolny powinien być używany tylko w szczególnych okolicznościach, ponieważ usługa, która obsługuje to powiadomienie, blokuje zamknięcie systemu do momentu zatrzymania usługi lub wygaśnięcia interwału przekroczenia limitu czasu przed upływem.
Po zakończeniu powiadomień przedshutdown wszystkie programy obsługi kontrolek, które wywołały SetServiceStatus z kodem kontrolnym SERVICE_ACCEPT_SHUTDOWN otrzymają kod kontrolny SERVICE_CONTROL_SHUTDOWN. Są one powiadamiane w kolejności, w której są wyświetlane w bazie danych zainstalowanych usług. Domyślnie usługa ma około 20 sekund do wykonania zadań oczyszczania przed zamknięciem systemu. Po upływie tego czasu zamknięcie systemu będzie kontynuowane niezależnie od tego, czy zamknięcie usługi zostało zakończone. Należy pamiętać, że jeśli system pozostanie w stanie zamknięcia (nie został uruchomiony ponownie lub wyłączony), usługa będzie nadal działać.
Jeśli usługa wymaga więcej czasu na oczyszczenie, wysyła STOP_PENDING komunikatów o stanie, wraz z wskazówką oczekiwania, więc kontroler usługi wie, jak długo czekać przed raportowaniem do systemu, że zamknięcie usługi zostało zakończone. Jednak aby zapobiec zatrzymaniu zamykania usługi, istnieje limit czasu oczekiwania kontrolera usługi. Jeśli usługa jest zamykana za pośrednictwem przystawki Usługi, limit wynosi 125 sekund lub 125 000 milisekund. Jeśli system operacyjny jest ponownie uruchamiany, limit czasu jest określony w WaitToKillServiceTimeout wartość (w milisekundach) następującego klucza rejestru:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
Ważny
Usługa nie powinna podejmować próby zwiększenia limitu czasu przez zmodyfikowanie tej wartości. Jeśli musisz ustawić WaitToKillServiceTimeout ręcznie, wartość powinna być w milisekundach.
Klienci wymagają szybkiego zamknięcia systemu operacyjnego. Jeśli na przykład komputer z zasilaniem UPS nie może zakończyć się zamknięciem, zanim upadnie z zasilania, dane mogą zostać utracone. W związku z tym usługi powinny wykonywać zadania oczyszczania tak szybko, jak to możliwe. Dobrym rozwiązaniem jest zminimalizowanie niezapisanych danych przez regularne zapisywanie danych, śledzenie danych zapisanych na dysku i zapisywanie tylko niezapisanych danych podczas zamykania. Ponieważ komputer jest zamykany, nie poświęcaj czasu na zwalnianie przydzielonej pamięci ani innych zasobów systemowych. Jeśli chcesz powiadomić serwer o wyjściu, zminimalizuj czas oczekiwania na odpowiedź, ponieważ problemy z siecią mogą opóźnić zamknięcie usługi.
Należy pamiętać, że podczas zamykania usługi program SCM domyślnie nie bierze pod uwagę zależności. Narzędzie SCM wylicza listę uruchomionych usług i wysyła polecenie SERVICE_CONTROL_SHUTDOWN. W związku z tym usługa może zakończyć się niepowodzeniem, ponieważ inna usługa, od niej zależy, została już zatrzymana.
Aby ręcznie ustawić kolejność zamykania usług, utwórz wielociągową wartość rejestru zawierającą nazwy usług w kolejności, w której należy je zamknąć i przypisać ją do wartości PreshutdownOrder klucza sterującego w następujący sposób:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PreshutdownOrder="Shutdown Order"
Aby ustawić kolejność zamykania usług zależnych z aplikacji, użyj funkcji SetProcessShutdownParameters. Program SCM używa tej funkcji, aby nadać jej program obsługi 0x1E0 priorytet. Narzędzie SCM wysyła SERVICE_CONTROL_SHUTDOWN powiadomienia, gdy wywoływana jest jego procedura obsługi sterowania i czeka na zakończenie działania usług przed powrotem z programu obsługi sterowania.
Tematy pokrewne
-
pisanie funkcji obsługi kontrolek