Bagikan melalui


Fungsi ServiceMain

Ketika program kontrol layanan meminta agar layanan baru berjalan, 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.

Fungsi ServiceMain harus melakukan tugas-tugas berikut:

  1. Menginisialisasi semua variabel global.

  2. Panggil fungsi RegisterServiceCtrlHandler segera untuk mendaftarkan fungsi Handler untuk menangani permintaan kontrol untuk layanan. Nilai pengembalian RegisterServiceCtrlHandler adalah handel status layanan yang akan digunakan dalam panggilan untuk memberi tahu SCM tentang status layanan.

  3. 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 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 inisialisasi ini direkomendasikan untuk performa, terutama untuk layanan mulai otomatis.

    • 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 fungsi SetServiceStatus 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 membuat kemajuan dan memblokir layanan lain agar tidak dimulai. 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 inkremental kepada pengguna.

  4. Ketika inisialisasi selesai, panggil SetServiceStatus untuk mengatur status layanan ke SERVICE_RUNNING dan tentukan kontrol yang disiapkan untuk diterima layanan. Untuk daftar kontrol, lihat struktur SERVICE_STATUS .

  5. Lakukan tugas layanan, atau, jika tidak ada tugas yang tertunda, kembalikan kontrol ke pemanggil. Setiap perubahan dalam status layanan menjamin panggilan ke SetServiceStatus untuk melaporkan informasi status baru.

  6. 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 mengakhiri. Pastikan untuk mengatur anggota dwServiceSpecificExitCode dan dwWin32ExitCode dari struktur SERVICE_STATUS untuk mengidentifikasi kesalahan.

Menulis Fungsi ServiceMain