次の方法で共有


サービス状態の遷移

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

サービスの初期状態はSERVICE_STOPPED。 SCM は、サービスを開始するときに、サービスの状態をSERVICE_START_PENDINGに設定し、サービスの ServiceMain 関数を呼び出します。 サービスは、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