サービスのスタートアップ
サービスまたはドライバー サービスを開始するために、サービス制御プログラムは 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が返されます。
詳細については、「サービスの開始」を参照してください。