Share via


LPSERVICE_MAIN_FUNCTIONA コールバック関数 (winsvc.h)

サービスのエントリ ポイント。

LPSERVICE_MAIN_FUNCTION型は、このコールバック関数へのポインターを定義します。 ServiceMain は、アプリケーション定義関数名のプレースホルダーです。

構文

LPSERVICE_MAIN_FUNCTIONA LpserviceMainFunctiona;

void LpserviceMainFunctiona(
  [in] DWORD dwNumServicesArgs,
  [in] LPSTR *lpServiceArgVectors
)
{...}

パラメーター

[in] dwNumServicesArgs

lpServiceArgVectors 配列内の引数の数。

[in] lpServiceArgVectors

サービスを開始した StartService 関数の呼び出しによってサービスに渡される null で終わる引数文字列。 引数がない場合、このパラメーターには NULL を指定できます。 それ以外の場合、最初の引数 (lpServiceArgVectors[0]) はサービスの名前であり、その後に追加の引数 (lpServiceArgVectors[1] から lpServiceArgVectors[dwNumServicesArgs-1]) が続きます。

ユーザーがコントロール パネルからサービス スナップインを使用して手動サービスを開始した場合、lpServiceArgVectors パラメーターの文字列はサービスのプロパティ ダイアログ ボックスから取得されます (サービス スナップインからサービス エントリを右クリックし、[プロパティ] をクリックし、[開始パラメーター] にパラメーターを入力します)。

戻り値

なし

解説

サービス プログラムは、1 つ以上のサービスを開始できます。 サービス プロセスには、開始できるサービスごとに SERVICE_TABLE_ENTRY 構造があります。 構造体は、サービス名と、そのサービスの ServiceMain 関数へのポインターを指定します。

サービス コントロール マネージャーは、サービスを開始する要求を受け取ると、サービス プロセスを開始します (まだ実行されていない場合)。 サービス プロセスのメイン スレッドは、SERVICE_TABLE_ENTRY構造体の配列へのポインターを使用して StartServiceCtrlDispatcher 関数呼び出します。 次に、サービス コントロール マネージャーは、このサービス プロセスの開始要求をサービス コントロール ディスパッチャーに送信します。 サービス コントロール ディスパッチャーは、開始されるサービスの ServiceMain 関数を実行する新しいスレッドを作成します。

ServiceMain 関数は、制御要求を処理する HandlerEx 関数を指定するために、RegisterServiceCtrlHandlerEx 関数を直ちに呼び出す必要があります。 次に、 SetServiceStatus 関数を呼び出して、状態情報をサービス コントロール マネージャーに送信する必要があります。 これらの呼び出しの後、関数はサービスの初期化を完了する必要があります。 ServiceMain 関数で別のサービスを開始しないでください。

サービス コントロール マネージャー (SCM) は、サービスがSERVICE_RUNNINGの状態を報告するまで待機します。 SCM との対話を必要とするシステム内の他のコンポーネントは、この期間中にブロックされるため、サービスはこの状態をできるだけ早く報告することをお勧めします。 一部の関数では、直接または間接的に SCM との対話が必要になる場合があります。

SCM は初期化中にサービス制御データベースをロックするため、サービスが初期化中に StartService を呼び出そうとすると、呼び出しはブロックされます。 サービスが正常に開始されたことを SCM に報告すると、 StartService を呼び出すことができます。 サービスで別のサービスを実行する必要がある場合、サービスは必要な依存関係を設定する必要があります。

さらに、サービスの初期化中にシステム関数を呼び出さないでください。 サービス コードは、SERVICE_RUNNINGの状態を報告した後にのみシステム関数を呼び出す必要があります。

ServiceMain 関数はグローバル イベントを作成し、このイベントに対して RegisterWaitForSingleObject 関数を呼び出して終了する必要があります。 これにより、 ServiceMain 関数を実行しているスレッドは終了しますが、サービスは終了しません。 サービスが停止している場合、サービス コントロール ハンドラーは SetServiceStatus をSERVICE_STOP_PENDINGで呼び出し、このイベントを通知する必要があります。 スレッド プールのスレッドは、待機コールバック関数を実行します。この関数は、グローバル イベントの終了を含むクリーンタスクを実行し、SERVICE_STOPPEDを使用して SetServiceStatus を呼び出す必要があります。 サービスが停止した後は、サービスが開始コントロールを受け取り、ServiceMain が再び呼び出された場合に競合状態が発生する可能性があるため、追加 のサービス コードを実行しないでください。 この問題は、複数のサービスがプロセスを共有する場合に発生する可能性が高くなります。

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

注意

winsvc.h ヘッダーは、LPSERVICE_MAIN_FUNCTIONをエイリアスとして定義し、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択します。 エンコードに依存しないエイリアスをエンコードニュートラルでないコードと組み合わせて使用すると、コンパイルまたはランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「 関数プロトタイプの規則」を参照してください。

要件

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

こちらもご覧ください

HandlerEx

RegisterServiceCtrlHandlerEx

RegisterWaitForSingleObject

SERVICE_TABLE_ENTRY

サービス関数

Service ServiceMain 関数

SetServiceStatus

StartServiceCtrlDispatcher