Bagikan melalui


Fungsi Handler Kontrol Layanan

Setiap layanan memiliki handler kontrol, fungsiHandler, 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 fungsiControlService. Semua layanan harus menerima dan memproses kode kontrol SERVICE_CONTROL_INTERROGATE. Anda dapat mengaktifkan atau menonaktifkan penerimaan kode kontrol lain dengan memanggil SetServiceStatus. Untuk menerima kode kontrol SERVICE_CONTROL_DEVICEEVENT, Anda harus memanggil fungsiRegisterDeviceNotification. Layanan juga dapat menangani kode kontrol tambahan yang ditentukan pengguna.

Jika layanan menerima kode kontrol SERVICE_CONTROL_STOP, layanan harus berhenti setelah diterima, masuk ke 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 boleh 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 fungsiChangeServiceConfig2). 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 penonaktifan selesai, semua handler 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 kedaluwarsa, 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 pesan status STOP_PENDING, bersama dengan petunjuk tunggu, sehingga pengontrol layanan tahu berapa lama menunggu sebelum melaporkan ke sistem bahwa pematian 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 pematian 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 tidak 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 pematian 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 pada 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 kunci Kontrol preshutdownOrder nilai, sebagai berikut:

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

Untuk mengatur urutan matikan layanan dependen dari aplikasi Anda, gunakan fungsiSetProcessShutdownParameters. 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