<Return[R]><Top>

RegisterServiceCtrlHandlerEx

Declare FFunction Api_RegisterServiceCtrlHandlerEx& Lib "advapi32" Alias "RegisterServiceCtrlHandlerEx" (ByVal lpServiceName$, ByRef lpHandlerProc As LPHANDLER_FUNCTION_EX, lpContext As Any)

Declare Function RegisterServiceCtrlHandlerEx Lib "advapi32" Alias "RegisterServiceCtrlHandlerEx" (ByVal lpServiceName As String, ByRef lpHandlerProc As LPHANDLER_FUNCTION_EX, lpContext As Any) As Long

サービスアプリケーションは RegisterServiceCtrlHandlerEx 関数を呼び出して、自らのサービス制御要求を処理する関数を登録する。
この関数は、RegisterServiceCtrlHandler 関数の改訂版である。サービスはどちらの関数を利用してもかまわないが、この新しい関数はユーザー定義のコンテキストデータをサポートし、新しいハンドラ関数は追加の拡張制御コードをサポートする。

パラメータ
lpServiceName
    [入力] 呼び出し側スレッドが動作させているサービスの名前を表す、NULL で終わる文字列へのポインタを指定する。これは、このサ

    ービスの作成時にサービス制御プログラムが CreateService 関数で指定したサービスの名前である。
lpHandlerProc
    [入力] 登録するハンドラ関数へのポインタを指定する。
lpContext
    [入力] ユーザー定義データを指定する。このパラメータはハンドラ関数へ渡されるもので、複数のサービスが 1 つのプロセスを共有すると

    きにサービスを識別するのに役立つ。

戻り値
    関数が成功すると、サービスステータスのハンドルが返る。
    関数が失敗すると、0 が返る。拡張エラー情報を取得するには、GetLastError 関数を使う。
    サービス制御マネージャは次のエラーコードを設定することがある。サービス制御マネージャが呼び出したレジストリ関数は、その他のエラー

    コードを設定することがある。

    エラーコード                                              

意味                                                                                                                 

    ERROR_INVALID_NAME

指定されたサービス名は無効である。

    ERROR_SERVICE_DOES_NOT_EXIST

指定されたサービスは存在しない。

 

解説
    新しいサービスの ServiceMain 関数は、即座に RegisterServiceCtrlHandlerEx 関数を呼び出して、制御ハンドラ関数を制御ディスパッチ

    ャに登録しなければならない。この結果、制御ディスパッチャはそのサービスに対する制御の要求を受け取ったときに、指定された関数を呼

    び出せるようになる。呼び出し側プロセスのスレッドは、この関数が返したサービスステータスのハンドルを使って、それ以降の

    SetServiceStatus 関数の呼び出しでこのサービスを識別することができる。
    SetServiceStatus 関数を最初に呼び出す前に、RegisterServiceCtrlHandlerEx 関数を呼び出さなければならない。ほかのサービスが誤っ

    てこのサービスのステータスを設定することがないよう、RegisterServiceCtrlHandlerEx 関数が呼び出し側用のサービスステータスのハンド

    ルを返すからである。加えて、サービスが制御ハンドラを指定する時点までに、制御の要求を受け取れるように制御ハンドラを実装しておかな

    ければならない。サービスは、SetServiceStatus 関数を通してこの制御ハンドラを受け入れる。
    制御の要求を指定して制御ハンドラ関数を呼び出した場合、制御ハンドラはサービスのステータスが変化したかどうかにかかわりなく、

    SetServiceStatus 関数を呼び出して自らの現在のステータスをサービス制御マネージャへ通知しなければならない。
    サービスステータスのハンドルを閉じる必要はない。