次の方法で共有


サービス状態の遷移

サービスは、その状態の変化をサービス コントロール マネージャー (SCM) に報告する役割を担います。 サービス制御プログラムとシステムは、SCM からのみサービスの状態を調べるので、サービスがその状態を正しく報告することが重要です。 サービスは、完全に初期化されたSERVICE_STATUS構造体へのポインターを使用して SetServiceStatus 関数を呼び出すことによって 、その状態SERVICE_STATUS 報告します。 構造体の dwCurrentState メンバーには、報告されるサービス状態が含まれています。

サービスの初期状態はSERVICE_STOPPED。 SCM は、サービスを開始すると、サービスの状態をSERVICE_START_PENDINGに設定し、サービスの ServiceMain 関数を呼び出します。 その後、サービスは、「 Service ServiceMain 関数」で説明されている手法のいずれかを使用して、初期化を完了します。 サービスが初期化を完了し、制御要求の受信を開始する準備ができたら、サービスは SetServiceStatus を呼び出してSERVICE_RUNNINGを報告し、サービスが受け入れる準備ができているコントロール要求を指定します。 SERVICE_START_PENDING から SERVICE_RUNNING への移行は、サービスが正常に開始されたことを SCM およびサービス監視ツールに示します。 サービスがSERVICE_RUNNING以外の状態を報告する場合、SCM またはサービス監視ツールは、サービスを開始に失敗したとマークする可能性があります。

SCM は、指定された制御要求のみをサービスに送信します (常に送信されるSERVICE_CONTROL_INTERROGATE要求を除きます)。 サービスが受け入れることができるコントロール要求の一覧については、SERVICE_STATUS構造体の dwControlsAccepted メンバーを参照してください。 デバイス イベントを受信するための登録の詳細については、 RegisterDeviceNotification 関数を参照してください。

通常、サービスの状態は、コントロール要求を処理した結果として変化します。 サービスの状態が変更される原因となる制御要求には、SERVICE_CONTROL_STOP、SERVICE_CONTROL_PAUSE、SERVICE_CONTROL_CONTINUEが含まれます。 これらの要求のいずれかを処理するためにサービスが長い処理を行う必要がある場合は、長い処理を実行するセカンダリ スレッドを作成し、対応する保留中の状態を SCM に報告する必要があります。 (Windows Vista 以降のバージョンの Windows で最適なパフォーマンスを得るには、この目的のために、サービスで スレッド プール のワーカー スレッドを使用する必要があります)。その後、サービスは、長い処理が完了したときに完了した状態遷移を報告する必要があります。 コントロール要求の処理の詳細については、「 サービス コントロール ハンドラー関数」を参照してください。

特定のサービス状態遷移のみが有効です。 次の図は、有効な遷移を示しています。

有効なサービス状態の遷移

SCM に報告されるサービス状態によって、SCM がサービスと対話する方法が決まります。 たとえば、サービスがSERVICE_STOP_PENDING報告した場合、この状態はサービスがシャットダウンしていることを示しているため、SCM はそれ以上の制御要求をサービスに送信しません。 サービスによって報告される次の状態は、SERVICE_STOP_PENDING後の唯一の有効な状態であるため、SERVICE_STOPPEDする必要があります。 ただし、サービスが無効な遷移を報告した場合、SCM は呼び出しに失敗しません。

次の図は、サービス制御プログラム (サービス クライアント) によって開始された制御要求や、SCM への状態変更を報告するためにサービスが行う SetServiceStatus 呼び出しなど、サービス状態の遷移をより詳細に示しています。 前述のように、SCM は、サービスが受け入れることを指定した制御要求のみを送信するため、図に示されているすべての要求がサービスで受信されない場合があります。

サービスの状態の遷移の詳細

ControlService

ControlServiceEx

SetServiceStatus