Fungsi ServiceMain
Ketika program kontrol layanan meminta layanan baru dijalankan, Service Control Manager (SCM) memulai layanan dan mengirim permintaan awal ke dispatcher kontrol. Dispatcher kontrol membuat utas baru untuk menjalankan fungsi ServiceMain untuk layanan. Misalnya, lihat Menulis Fungsi ServiceMain.
FungsiServiceMain harus melakukan tugas-tugas berikut:
Menginisialisasi semua variabel global.
Panggil fungsiRegisterServiceCtrlHandler untuk segera mendaftarkan fungsiHandleruntuk menangani permintaan kontrol untuk layanan. Nilai pengembalian RegisterServiceCtrlHandler adalah penanganan status layanan yang akan digunakan dalam panggilan untuk memberi tahu SCM tentang status layanan.
Lakukan inisialisasi. Jika waktu eksekusi kode inisialisasi diperkirakan sangat singkat (kurang dari satu detik), inisialisasi dapat dilakukan langsung di ServiceMain.
Jika waktu inisialisasi diperkirakan lebih dari satu detik, layanan harus menggunakan salah satu teknik inisialisasi berikut:
Panggil fungsi SetServiceStatus untuk melaporkan SERVICE_RUNNING tetapi tidak menerima kontrol hingga inisialisasi selesai. Layanan ini melakukan ini dengan memanggil SetServiceStatus dengan dwCurrentState diatur ke SERVICE_RUNNING dan dwControlsAccepted diatur ke 0 dalam struktur SERVICE_STATUS. Ini memastikan bahwa SCM tidak akan mengirim permintaan kontrol apa pun ke layanan sebelum siap dan membebaskan SCM untuk mengelola layanan lain. Pendekatan ini untuk inisialisasi direkomendasikan untuk performa, terutama untuk layanan autostart.
Laporkan SERVICE_START_PENDING, tidak menerima kontrol, dan tentukan petunjuk tunggu. Jika kode inisialisasi layanan Anda melakukan tugas yang diharapkan memakan waktu lebih lama dari nilai petunjuk tunggu awal, kode Anda harus memanggil SetServiceStatus fungsi secara berkala (mungkin dengan petunjuk tunggu yang direvisi) untuk menunjukkan bahwa kemajuan sedang dibuat. Pastikan untuk memanggil SetServiceStatus hanya jika inisialisasi mengalami kemajuan. Jika tidak, SCM dapat menunggu layanan Anda memasuki status SERVICE_RUNNING dengan asumsi bahwa layanan Anda mengalami kemajuan dan memblokir layanan lain dari awal. Jangan panggil SetServiceStatus dari utas terpisah kecuali Anda yakin utas yang melakukan inisialisasi benar-benar membuat kemajuan.
Layanan yang menggunakan pendekatan ini juga dapat menentukan nilai check-point dan menaikkan nilai secara berkala selama inisialisasi yang panjang. Program yang memulai layanan dapat memanggil QueryServiceStatus atau QueryServiceStatusEx untuk mendapatkan nilai check-point terbaru dari SCM dan menggunakan nilai untuk melaporkan kemajuan bertahap kepada pengguna.
Setelah inisialisasi selesai, panggil SetServiceStatus untuk mengatur status layanan ke SERVICE_RUNNING dan tentukan kontrol yang siap diterima layanan. Untuk daftar kontrol, lihat struktur SERVICE_STATUS.
Lakukan tugas layanan, atau, jika tidak ada tugas yang tertunda, kembalikan kontrol ke pemanggil. Setiap perubahan dalam status layanan menjamin panggilan keSetServiceStatusuntuk melaporkan informasi status baru.
Jika terjadi kesalahan saat layanan menginisialisasi atau berjalan, layanan harus memanggil SetServiceStatus untuk mengatur status layanan ke SERVICE_STOP_PENDING jika pembersihan akan panjang. Setelah pembersihan selesai, panggil SetServiceStatus untuk mengatur status layanan ke SERVICE_STOPPED dari utas terakhir untuk dihentikan. Pastikan untuk mengatur dwServiceSpecificExitCode dan dwWin32ExitCode anggota struktur SERVICE_STATUS untuk mengidentifikasi kesalahan.
Topik terkait
-
Menulis Fungsi ServiceMain