サービスの開始

サービスまたはドライバー サービスを開始するために、サービス制御プログラムは StartService 関数を使用します。 データベースがロックされている場合、 StartService 関数は失敗します。 この場合、サービス制御プログラムは数秒待機し、 StartService を再度呼び出す必要があります。 QueryServiceLockStatus 関数を呼び出すことで、データベースの現在のロック状態をチェックできます。

サービス制御プログラムがサービスを開始している場合は、 StartService 関数を使用して、サービスの ServiceMain 関数に渡される引数の配列を指定できます。 StartService 関数は、ServiceMain 関数を実行するために新しいスレッドが作成された後に を返します。 サービス制御プログラムは、QueryServiceStatus 関数を呼び出すことによって、SERVICE_STATUS構造で新しく開始されたサービスの状態を取得できます。 初期化中は、 dwCurrentState メンバーをSERVICE_START_PENDINGする必要があります。 dwWaitHint メンバーは、サービス制御プログラムが QueryServiceStatus を再度呼び出す前に待機する必要がある時間を示す時間間隔 (ミリ秒単位) です。 初期化が完了すると、サービスは dwCurrentState を SERVICE_RUNNING に変更します。

サービス コントロール マネージャーでは、起動時にカスタム環境変数をサービスに渡すことはサポートされていません。 また、サービス制御マネージャーは、サービスの実行中に環境変数の変更を検出して渡しません。 サービスを環境変数に依存させる代わりに、レジストリ値または ServiceMain 引数を使用します。

一般的なサービスがサービス コントロール マネージャーによって開始された場合の動作の簡単な概要を次に示します。

  • SCM は、レジストリからサービス パスを読み取り、サービスを開始する準備をします。 これには、サービス ロックの取得が含まれます。 サービス ロックが保持されている間に別のサービスを開始しようとすると、サービス ロックが解放されるまでブロックされます。
  • SCM はプロセスを開始し、子プロセスが終了するまで待機するか (エラーを示します)、SERVICE_RUNNING状態を報告します。
  • アプリケーションは非常に単純な初期化を実行し、 StartServiceCtrlDispatcher 関数を呼び出します。
  • StartServiceCtrlDispatcher は 、サービス コントロール マネージャーに接続し、サービスの ServiceMain 関数を呼び出す 2 つ目のスレッドを開始します。 ServiceMain は、できるだけ早くSERVICE_RUNNINGを報告する必要があります。
  • サービス コントロール マネージャーは、サービスが実行されていることを通知されると、サービス ロックを解放します。

サービスが 80 秒以内に状態を更新せず、最後の待機ヒントを加えた場合、サービス 制御マネージャーは、サービスが応答を停止したと判断します。 サービス コントロール マネージャーはイベントをログに記録し、サービスを停止します。

プログラムがドライバー サービスを開始している場合、デバイス ドライバーの初期化が完了した後に StartService が返されます。

詳細については、「 サービスの開始」を参照してください。