Share via


ServiceMain 函式

當服務控制程式要求執行新服務時,服務控制管理員 (SCM) 啟動服務,並將啟動要求傳送至控制發送器。 控制發送器會建立新的執行緒,以執行服務的 ServiceMain 函式。 如需範例,請參閱 撰寫 ServiceMain 函式

ServiceMain函式應該執行下列工作:

  1. 初始化所有全域變數。

  2. 立即呼叫 RegisterServiceCtrlHandler 函式,以註冊 Handler 函式來處理服務的控制要求。 RegisterServiceCtrlHandler的傳回值是服務狀態控制碼,用於呼叫以通知 SCM 的服務狀態。

  3. 執行初始化。 如果初始化程式碼的執行時間應該非常短, (少於一秒) ,則可以直接在 ServiceMain中執行初始化。

    如果初始化時間預期超過一秒,服務應該使用下列其中一種初始化技術:

    • 呼叫 SetServiceStatus 函式來報告SERVICE_RUNNING,但在初始化完成之前不接受任何控制項。 服務會呼叫 SetServiceStatus 並將 dwCurrentState 設定為 SERVICE_RUNNING,並將 dwControlsAccepted 設定為 SERVICE_STATUS 結構中的 0 來執行這項作業。 這可確保 SCM 在準備好之前,不會將任何控制要求傳送至服務,並釋放 SCM 來管理其他服務。 建議使用這個初始化方法來達到效能,特別是針對自動啟動服務。

    • 報表SERVICE_START_PENDING、不接受任何控制項,並指定等候提示。 如果您的服務初始化程式碼執行預期花費的時間超過初始等候提示值的工作,您的程式碼必須定期呼叫 SetServiceStatus 函式, (可能已修改的等候提示) ,以指出正在進行進度。 只有當初始化正在進行時,請務必呼叫 SetServiceStatus 。 否則,SCM 可以等候您的服務進入SERVICE_RUNNING狀態,假設您的服務正在進行中,並封鎖其他服務無法啟動。 除非您確定執行初始化的執行緒確實正在進行進度,否則請勿從個別執行緒呼叫 SetServiceStatus

      使用此方法的服務也可以指定檢查點值,並在冗長的初始化期間定期遞增值。 啟動服務的程式可以呼叫QueryServiceStatus 或 QueryServiceStatusEx,以從 SCM 取得最新的檢查點值,並使用值向使用者報告累加進度。

  4. 初始化完成時,請呼叫 SetServiceStatus 將服務狀態設定為 SERVICE_RUNNING,並指定服務準備接受的控制項。 如需控制項清單,請參閱 SERVICE_STATUS 結構。

  5. 執行服務工作,如果沒有擱置的工作,請將控制權傳回給呼叫端。 服務狀態中的任何變更都保證呼叫 SetServiceStatus 來報告新的狀態資訊。

  6. 如果服務初始化或執行時發生錯誤,服務應該呼叫 SetServiceStatus ,將服務狀態設定為SERVICE_STOP_PENDING清除將會冗長。 清除完成後,請呼叫 SetServiceStatus ,將服務狀態設定為從最後一個執行緒終止SERVICE_STOPPED。 請務必設定SERVICE_STATUS結構的dwServiceSpecificExitCodedwWin32ExitCode成員,以識別錯誤。

撰寫 ServiceMain 函式