SetServiceStatus 関数 (winsvc.h)

呼び出し元サービスのサービス コントロール マネージャーの状態情報を更新します。

構文

BOOL SetServiceStatus(
  [in] SERVICE_STATUS_HANDLE hServiceStatus,
  [in] LPSERVICE_STATUS      lpServiceStatus
);

パラメーター

[in] hServiceStatus

現在のサービスの状態情報構造へのハンドル。 このハンドルは RegisterServiceCtrlHandlerEx 関数によって返されます。

[in] lpServiceStatus

呼び出し元サービスの最新の状態情報を含む、 SERVICE_STATUS 構造体へのポインター。

戻り値

関数が成功すると、戻り値は 0 以外になります。

関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。

サービス コントロール マネージャーでは、次のエラー コードを設定できます。 その他のエラー コードは、サービス コントロール マネージャーによって呼び出されるレジストリ関数によって設定できます。

リターン コード 説明
ERROR_INVALID_DATA
指定されたサービス状態構造が無効です。
ERROR_INVALID_HANDLE
指定されたハンドルが無効です。

注釈

ServiceMain 関数は、まず RegisterServiceCtrlHandlerEx 関数を呼び出して、サービスのSERVICE_STATUS_HANDLEを取得します。 その後すぐに SetServiceStatus 関数を呼び出して、その状態がSERVICE_START_PENDINGであることをサービス コントロール マネージャーに通知します。 初期化中、サービスは更新された状態を提供して、進行状況を示すことができますが、より多くの時間が必要であることを示します。 一般的なバグは、別のスレッドが SetServiceStatus を引き続き呼び出してサービス コントロール マネージャーがハングとしてマークするのを防ぐ間に、サービスがメイン スレッドに初期化を実行させる点です。 ただし、メインスレッドがハングすると、ワーカー スレッドはメイン スレッドが進行していることを報告し続けるので、サービスの開始は無限ループで終了します。

コントロール要求を処理した後、サービスの状態が変更された場合、サービスの Handler 関数は SetServiceStatus を呼び出して、新しい状態をサービス コントロール マネージャーに報告する必要があります。 これは、サービスが停止またはシャットダウン制御を処理している場合など、サービスの状態が変化している場合にのみ必要です。 サービスは、サービスの任意のスレッドからいつでもこの関数を使用して、回復可能なエラーのためにサービスを停止する必要がある場合など、状態の変更をサービス 制御マネージャーに通知することもできます。

サービスは、 RegisterServiceCtrlHandlerEx を呼び出してサービス状態ハンドルを取得した後にのみ、この関数を呼び出すことができます。

サービスが setServiceStatus を呼び出し、 dwCurrentState メンバーを SERVICE_STOPPED に設定し、 dwWin32ExitCode メンバーを 0 以外の値に設定すると、次のエントリがシステム イベント ログに書き込まれます。

   Event ID    = 7023
   Source      = Service Control Manager
   Type        = Error
   Description = <ServiceName> terminated with the following error:
                 <ExitCode>.

この関数を呼び出すときのベスト プラクティスを次に示します。

  • SERVICE_STATUS構造体内のすべてのフィールドを初期化し、保留中の状態に対して有効なチェックポイント値と待機ヒント値があることを確認します。 妥当な待機ヒントを使用します。
  • 状態がSERVICE_START_PENDINGされているか、サービスがクラッシュする可能性がある場合は、コントロールを受け入れるように登録しないでください。 初期化が完了したら、SERVICE_CONTROL_STOPコードを受け入れます。
  • チェックポイントと待機ヒント値を指定してこの関数を呼び出すのは、保留中の開始、停止、一時停止、または続行操作に関連するタスクでサービスが進行している場合のみです。 それ以外の場合、SCM はサービスがハングしているかどうかを検出できません。
  • ServiceMain が失敗した場合は、適切な終了コードで停止状態を入力します。
  • 状態がSERVICE_STOPPED場合は、必要なすべてのクリーンアップを実行し、 SetServiceStatus を 1 回だけ呼び出します。 この関数は、SCM に対して LRPC 呼び出しを行います。 SERVICE_STOPPED状態の関数を最初に呼び出すと、RPC コンテキスト ハンドルが閉じられ、後続の呼び出しによってプロセスがクラッシュする可能性があります。
  • サービス プロセスはいつでも終了できるため、SERVICE_STOPPEDで SetServiceStatus を呼び出した後に追加の作業を実行しないでください。

例については、「 ServiceMain 関数の記述」を参照してください。

要件

要件
サポートされている最小のクライアント Windows XP (デスクトップ アプリのみ)
サポートされている最小のサーバー Windows Server 2003 (デスクトップ アプリのみ)
対象プラットフォーム Windows
ヘッダー winsvc.h (Windows.h を含む)
Library Advapi32.lib
[DLL] Advapi32.dll

こちらもご覧ください

HandlerEx

RegisterServiceCtrlHandlerEx

SERVICE_STATUS

サービス関数

ServiceMain

SetServiceBits