Bagikan melalui


Fungsi Handler Kontrol Layanan

Setiap layanan memiliki handler kontrol, fungsi Handler , yang dipanggil oleh dispatcher kontrol ketika proses layanan menerima permintaan kontrol dari program kontrol layanan. Oleh karena itu, fungsi ini dijalankan dalam konteks dispatcher kontrol. Misalnya, lihat Menulis Fungsi Handler Kontrol.

Layanan memanggil fungsi RegisterServiceCtrlHandler atau RegisterServiceCtrlHandlerEx untuk mendaftarkan fungsi handler kontrol layanannya.

Ketika handler kontrol layanan dipanggil, layanan harus memanggil fungsi SetServiceStatus untuk melaporkan statusnya ke SCM hanya jika menangani kode kontrol menyebabkan status layanan berubah. Jika menangani kode kontrol tidak menyebabkan status layanan berubah, tidak perlu memanggil SetServiceStatus.

Program kontrol layanan dapat mengirim permintaan kontrol menggunakan fungsi ControlService . Semua layanan harus menerima dan memproses kode kontrol SERVICE_CONTROL_INTERROGATE . Anda dapat mengaktifkan atau menonaktifkan penerimaan kode kontrol lainnya dengan memanggil SetServiceStatus. Untuk menerima kode kontrol SERVICE_CONTROL_DEVICEEVENT , Anda harus memanggil fungsi RegisterDeviceNotification . Layanan juga dapat menangani kode kontrol tambahan yang ditentukan pengguna.

Jika layanan menerima kode kontrol SERVICE_CONTROL_STOP , layanan harus berhenti setelah diterima, akan status SERVICE_STOP_PENDING atau SERVICE_STOPPED . Setelah SCM mengirim kode kontrol ini, SCM tidak akan mengirim kode kontrol lainnya.

Windows XP: Jika layanan mengembalikan NO_ERROR dan terus berjalan, layanan terus menerima kode kontrol. Perilaku ini berubah dimulai dengan Windows Server 2003 dan Windows XP dengan Paket Layanan 2 (SP2).

Handler kontrol harus kembali dalam waktu 30 detik, atau SCM mengembalikan kesalahan. Jika layanan harus melakukan pemrosesan yang panjang ketika layanan menjalankan handler kontrol, layanan harus membuat utas sekunder untuk melakukan pemrosesan yang panjang, lalu kembali dari handler kontrol. Ini mencegah layanan mengikat dispatcher kontrol. Misalnya, saat menangani permintaan berhenti untuk layanan yang membutuhkan waktu lama, buat utas lain untuk menangani proses penghentian. Handler kontrol hanya harus memanggil SetServiceStatus dengan pesan SERVICE_STOP_PENDING dan kembali.

Saat pengguna mematikan sistem, semua handler kontrol yang telah memanggil SetServiceStatus dengan kode kontrol SERVICE_ACCEPT_PRESHUTDOWN menerima kode kontrol SERVICE_CONTROL_PRESHUTDOWN . Manajer kontrol layanan menunggu hingga layanan berhenti atau nilai batas waktu penonaktifan yang ditentukan kedaluwarsa (nilai ini dapat diatur dengan fungsi ChangeServiceConfig2 ). Kode kontrol ini harus digunakan hanya dalam keadaan khusus, karena layanan yang menangani pemberitahuan ini memblokir pematian sistem hingga layanan berhenti atau interval waktu habis sebelum waktu habis berakhir.

Setelah pemberitahuan preshutdown selesai, semua penangan kontrol yang telah memanggil SetServiceStatus dengan kode kontrol SERVICE_ACCEPT_SHUTDOWN menerima kode kontrol SERVICE_CONTROL_SHUTDOWN . Mereka diberi tahu dalam urutan bahwa mereka muncul dalam database layanan yang diinstal. Secara default, layanan memiliki sekitar 20 detik untuk melakukan tugas pembersihan sebelum sistem dimatikan. Setelah waktu ini berakhir, pematian sistem berlanjut terlepas dari apakah pematian layanan selesai. Perhatikan bahwa jika sistem dibiarkan dalam status matikan (tidak dimulai ulang atau dimatikan), layanan terus berjalan.

Jika layanan membutuhkan lebih banyak waktu untuk membersihkan, layanan mengirim STOP_PENDING pesan status, bersama dengan petunjuk tunggu, sehingga pengontrol layanan tahu berapa lama menunggu sebelum melaporkan ke sistem bahwa penonaktifan layanan selesai. Namun, untuk mencegah layanan menghentikan pematian, ada batasan berapa lama pengontrol layanan menunggu. Jika layanan dimatikan melalui snap-in Layanan, batasnya adalah 125 detik, atau 125.000 milidetik. Jika sistem operasi dimulai ulang, batas waktu ditentukan dalam nilai WaitToKillServiceTimeout (dalam milidetik) dari kunci registri berikut:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

Penting

Layanan tidak boleh mencoba meningkatkan batas waktu dengan memodifikasi nilai ini. Jika Anda perlu mengatur WaitToKillServiceTimeout secara manual, nilainya harus dalam milidetik.

Pelanggan memerlukan penonaktifan sistem operasi yang cepat. Misalnya, jika komputer yang berjalan pada daya UPS tidak dapat menyelesaikan pematian sebelum UPS kehabisan daya, data dapat hilang. Oleh karena itu, layanan harus menyelesaikan tugas pembersihan mereka secepat mungkin. Ini adalah praktik yang baik untuk meminimalkan data yang tidak disimpan dengan menyimpan data secara teratur, melacak data yang disimpan ke disk, dan hanya menyimpan data Anda yang belum disimpan saat dimatikan. Karena komputer sedang dimatikan, jangan menghabiskan waktu untuk melepaskan memori yang dialokasikan atau sumber daya sistem lainnya. Jika Anda perlu memberi tahu server bahwa Anda keluar, minimalkan waktu yang dihabiskan untuk menunggu balasan, karena masalah jaringan dapat menunda penonaktifan layanan Anda.

Perhatikan bahwa selama penonaktifan layanan, secara default, SCM tidak mempertimbangkan dependensi. SCM menghitung daftar layanan yang sedang berjalan dan mengirim perintah SERVICE_CONTROL_SHUTDOWN . Oleh karena itu, layanan mungkin gagal karena layanan lain yang bergantung padanya telah berhenti.

Untuk mengatur urutan matikan layanan secara manual, buat nilai registri multistring yang berisi nama layanan dalam urutan di mana layanan harus dimatikan dan tetapkan ke nilai PreshutdownOrder kunci kontrol, sebagai berikut:

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

Untuk mengatur urutan matikan layanan dependen dari aplikasi Anda, gunakan fungsi SetProcessShutdownParameters . SCM menggunakan fungsi ini untuk memberikan penangannya 0x1E0 prioritas. SCM mengirimkan pemberitahuan SERVICE_CONTROL_SHUTDOWN ketika handler kontrolnya dipanggil dan menunggu layanan keluar sebelum kembali dari handler kontrolnya.

Menulis Fungsi Handler Kontrol