<Return[R]><Top>

RegisterServiceCtrlHandler

Declare Function Api_RegisterServiceCtrlHandler& Lib "advapi32" Alias "RegisterServiceCtrlHandlerA" (ByVal lpServiceName$, ByVal lpHandlerProc&)

Declare Function RegisterServiceCtrlHandler Lib "advapi32" Alias "RegisterServiceCtrlHandlerA" (ByVal lpServiceName As String, ByVal lpHandlerProc As Long) As Long

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

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

    ビスの作成時にサービス制御プログラムが CreateService 関数で指定したサービスの名前である。
    サービスタイプが SERVICE_WIN32_OWN_PROCESS の場合は、プロセス内にただ 1 つの登録済みサービスが存在するので、この関数

    は指定された名前が有効かどうかを検証しない。
lpHandlerProc
    [入力]登録するハンドラ関数へのポインタを指定する。

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

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

    エラーコード                                              

意味                                                                                                                 

    ERROR_INVALID_NAME

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

    ERROR_SERVICE_DOES_NOT_EXIST

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

 

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

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

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

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

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

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

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

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