Aracılığıyla paylaş


Hizmet Denetimi İşleyici İşlevi

Her hizmetin, hizmet işlemi bir hizmet denetim programından denetim isteği aldığında denetim dağıtıcısı tarafından çağrılan İşleyicisi işlevi olan bir denetim işleyicisi vardır. Bu nedenle, bu işlev denetim dağıtıcısı bağlamında yürütülür. Örnek için bkz. Denetim İşleyicisi İşlevi Yazma.

Hizmet, hizmet denetimi işleyici işlevini kaydetmek için RegisterServiceCtrlHandlerveya RegisterServiceCtrlHandlerExişleviniçağırır.

Hizmet denetimi işleyicisi çağrıldığında, hizmetin durumunu SCM'ye raporlamak için SetServiceStatus işlevini çağırması gerekir ancak denetim kodunun işlenmesi hizmet durumunun değişmesine neden oluyorsa. Denetim kodunun işlenmesi hizmet durumunun değişmesine neden olmazsa SetServiceStatus çağrı yapılması gerekmez.

Hizmet denetim programı, ControlService işlevini kullanarak denetim istekleri gönderebilir. Tüm hizmetlerin SERVICE_CONTROL_INTERROGATE denetim kodunu kabul etmesi ve işlemesi gerekir. SetServiceStatusçağırarak diğer denetim kodlarının kabul edilmesini etkinleştirebilir veya devre dışı bırakabilirsiniz. SERVICE_CONTROL_DEVICEEVENT denetim kodunu almak için RegisterDeviceNotification işlevini çağırmanız gerekir. Hizmetler kullanıcı tanımlı ek denetim kodlarını da işleyebilir.

Bir hizmet SERVICE_CONTROL_STOP denetim kodunu kabul ederse, SERVICE_STOP_PENDING veya SERVICE_STOPPED durumuna giderek alındıktan sonra durması gerekir. SCM bu denetim kodunu gönderdikten sonra diğer denetim kodlarını göndermez.

Windows XP: Hizmet NO_ERROR döndürür ve çalışmaya devam ederse, denetim kodlarını almaya devam eder. Bu davranış, Windows Server 2003 ve Windows XP Service Pack 2 (SP2) ile başlayarak değişti.

Denetim işleyicisi 30 saniye içinde döndürülmelidir veya SCM bir hata döndürür. Hizmet denetim işleyicisini yürütürken hizmetin uzun işleme yapması gerekiyorsa, uzun işlemeyi gerçekleştirmek için ikincil bir iş parçacığı oluşturmalı ve ardından denetim işleyicisinden döndürmelidir. Bu, hizmetin denetim dağıtıcısını bağlamasını engeller. Örneğin, uzun süren bir hizmetin durdurma isteğini işlerken durdurma işlemini işlemek için başka bir iş parçacığı oluşturun. Denetim işleyicisi, SERVICE_STOP_PENDING iletisiyle SetServiceStatus çağırmalı ve döndürmelidir.

Kullanıcı sistemi kapattığında, SERVICE_ACCEPT_PRESHUTDOWN denetim koduyla SetServiceStatus çağıran tüm denetim işleyicileri SERVICE_CONTROL_PRESHUTDOWN denetim kodunu alır. Hizmet denetim yöneticisi, hizmet durdurulana veya belirtilen önshutdown zaman aşımı değerinin süresi dolana kadar bekler (bu değer ChangeServiceConfig2işleviayarlanabilir). Bu bildirimi işleyen bir hizmet, hizmet durdurulana veya ön oturum açma zaman aşımı aralığı dolana kadar sistemin kapatılmasını engellediğinden, bu denetim kodu yalnızca özel durumlarda kullanılmalıdır.

Preshutdown bildirimleri tamamlandıktan sonra, SERVICE_ACCEPT_SHUTDOWN denetim koduyla SetServiceStatus çağıran tüm denetim işleyicileri SERVICE_CONTROL_SHUTDOWN denetim kodunu alır. Bu kişiler, yüklü hizmetlerin veritabanında göründükleri sırayla bildirilir. Varsayılan olarak, bir hizmetin sistem kapanmadan önce temizleme görevlerini gerçekleştirmek için yaklaşık 20 saniyesi vardır. Bu süre dolduktan sonra, hizmet kapatmanın tamamlanıp tamamlanmadığına bakılmaksızın sistem kapatma işlemi devam eder. Sistem kapatma durumunda bırakılırsa (yeniden başlatılmaz veya kapatılmazsa), hizmetin çalışmaya devam ettiğini unutmayın.

Hizmetin temizlenmesi için daha fazla zaman gerekiyorsa, hizmet denetleyicisinin hizmete kapatma işleminin tamamlandığını raporlamadan önce ne kadar bekleyeceğini bilmesi için bekleme ipucuyla birlikte STOP_PENDING durum iletileri gönderir. Ancak, bir hizmetin kapatmayı durdurmasını önlemek için, hizmet denetleyicisinin bekleme süresiyle ilgili bir sınır vardır. Hizmet Hizmetler ek bileşeni aracılığıyla kapatılıyorsa sınır 125 saniye veya 125.000 milisaniyedir. İşletim sistemi yeniden başlatılıyorsa, süre sınırı aşağıdaki kayıt defteri anahtarının WaitToKillServiceTimeout değeri (milisaniye) belirtilir:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

Önemli

Bir hizmet, bu değeri değiştirerek zaman sınırını artırmaya çalışmamalıdır. WaitToKillServiceTimeout el ile ayarlamanız gerekiyorsa, değer milisaniye cinsinden olmalıdır.

Müşteriler, işletim sisteminin hızlı bir şekilde kapatılmasını gerektirir. Örneğin, UPS gücünde çalışan bir bilgisayar, UPS'nin gücü bitmeden kapatma işlemini tamamlayamazsa veriler kaybolabilir. Bu nedenle, hizmetler temizleme görevlerini mümkün olan en kısa sürede tamamlamalıdır. Verileri düzenli aralıklarla kaydederek, diske kaydedilen verileri izleyerek ve yalnızca kaydedilmemiş verilerinizi kapatıldığında kaydederek kaydedilmemiş verileri en aza indirmek iyi bir uygulamadır. Bilgisayar kapatıldığı için ayrılan belleği veya diğer sistem kaynaklarını serbest bırakmak için zaman harcamayın. Bir sunucudan çıktığınızı bildirmeniz gerekiyorsa, ağ sorunları hizmetinizin kapatılmasını geciktirebileceğinden yanıt beklerken harcanan süreyi en aza indirin.

Hizmet kapatma sırasında SCM'nin varsayılan olarak bağımlılıkları dikkate almadığını unutmayın. SCM, çalışan hizmetlerin listesini numaralandırır ve SERVICE_CONTROL_SHUTDOWN komutunu gönderir. Bu nedenle, bağlı olduğu başka bir hizmet zaten durdurulduğu için bir hizmet başarısız olabilir.

Hizmetlerin kapatma sırasını el ile ayarlamak için, hizmet adlarını kapatmaları gereken sırayla içeren bir çok dizeli kayıt defteri değeri oluşturun ve aşağıdaki gibi Denetim anahtarının PreshutdownOrder değerine atayın:

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

Uygulamanızdan bağımlı hizmetlerin kapatma sırasını ayarlamak için SetProcessShutdownParametersişlevinikullanın. SCM, işleyicisine 0x1E0 öncelik vermek için bu işlevi kullanır. SCM, denetim işleyicisi çağrıldığında SERVICE_CONTROL_SHUTDOWN bildirimleri gönderir ve denetim işleyicisinden dönmeden önce hizmetlerin çıkmasını bekler.

Denetim İşleyicisi İşlevi yazma