LPHANDLER_FUNCTION_EX コールバック関数 (winsvc.h)
RegisterServiceCtrlHandlerEx 関数で使用されるアプリケーション定義のコールバック関数。 サービス プログラムは、特定のサービスのコントロール ハンドラー関数として使用できます。
LPHANDLER_FUNCTION_EX型は、この関数へのポインターを定義します。 HandlerEx は、アプリケーション定義名のプレースホルダーです。
この関数は、RegisterServiceCtrlHandler 関数で使用されるハンドラー コントロール ハンドラー関数よりも優先されます。 サービスではいずれかのコントロール ハンドラーを使用できますが、新しいコントロール ハンドラーでは、ユーザー定義のコンテキスト データと追加の拡張コントロール コードがサポートされます。
構文
LPHANDLER_FUNCTION_EX LphandlerFunctionEx;
DWORD LphandlerFunctionEx(
[in] DWORD dwControl,
[in] DWORD dwEventType,
[in] LPVOID lpEventData,
[in] LPVOID lpContext
)
{...}
パラメーター
[in] dwControl
コントロール コード。 このパラメーターには、次の値のいずれかを指定できます。
制御コード | 意味 |
---|---|
|
一時停止したサービスに再開する必要があることを通知します。 |
|
現在の状態情報をサービス コントロール マネージャーに報告するようにサービスに通知します。
ハンドラーは単に NO_ERRORを返す必要があります。SCM はサービスの現在の状態を認識します。 |
|
バインド用の新しいコンポーネントがあることをネットワーク サービスに通知します。 サービスは新しいコンポーネントにバインドする必要があります。
アプリケーションでは、代わりにプラグ アンド プレイ機能を使用する必要があります。 |
|
いずれかのバインディングが無効になっていることをネットワーク サービスに通知します。 サービスは、そのバインディング情報を再読み取りし、バインドを削除する必要があります。
アプリケーションでは、代わりにプラグ アンド プレイ機能を使用する必要があります。 |
|
無効なバインディングが有効になっていることをネットワーク サービスに通知します。 サービスは、そのバインディング情報を再読み取りし、新しいバインディングを追加する必要があります。
アプリケーションでは、代わりにプラグ アンド プレイ機能を使用する必要があります。 |
|
バインド用のコンポーネントが削除されたことをネットワーク サービスに通知します。 サービスは、そのバインディング情報を再読み取りし、削除されたコンポーネントからバインドを解除する必要があります。
アプリケーションでは、代わりにプラグ アンド プレイ機能を使用する必要があります。 |
|
サービス固有のスタートアップ パラメーターが変更されたことをサービスに通知します。 サービスは、そのスタートアップ パラメーターを再読み取りする必要があります。 |
|
一時停止する必要があることをサービスに通知します。 |
|
システムがシャットダウンされることをサービスに通知します。 システムのシャットダウン時に厳しい時間制限を超えてクリーンアップ タスクを実行するために追加の時間が必要なサービスは、この通知を使用できます。 サービス コントロール マネージャーは、この通知を登録したアプリケーションに送信してから、その通知に登録されているアプリケーションに SERVICE_CONTROL_SHUTDOWN 通知を送信します。
この通知を処理するサービスは、サービスが停止するか、SERVICE_PRESHUTDOWN_INFOで指定された事前シャットダウンタイムアウト間隔が切れるまで、システム のシャットダウンを ブロックします。 これはユーザー エクスペリエンスに影響するため、サービスでは、次のシステム起動時にデータの損失や大幅な復旧時間を回避する必要がある場合にのみ、この機能を使用する必要があります。 Windows Server 2003 および Windows XP: この値はサポートされていません。 |
|
サービスがクリーンアップ タスクを実行できるように、システムがシャットダウンしていることをサービスに通知します。 SERVICE_CONTROL_PRESHUTDOWN通知に登録するサービスは、既に停止しているため、この通知を受信できないことに注意してください。
サービスがこのコントロール コードを受け入れる場合は、クリーンアップ タスクを実行した後に停止し、 NO_ERRORを返す必要があります。 SCM は、このコントロール コードを送信した後、他のコントロール コードをサービスに送信しません。 詳細については、このトピックの「解説」セクションを参照してください。 |
|
停止する必要があることをサービスに通知します。
サービスがこの制御コードを受け入れる場合は、受信時に停止し、 NO_ERRORを返す必要があります。 SCM は、このコントロール コードを送信した後、他のコントロール コードをサービスに送信しません。 Windows XP: サービスが NO_ERROR を返し、実行を続ける場合は、制御コードを受け取り続けます。 この動作は、Windows Server 2003 および WINDOWS XP SP2 以降で変更されました。 |
このパラメーターには、次のいずれかの拡張制御コードを指定することもできます。 これらのコントロール コードは Handler 関数ではサポートされていないことに注意してください。
制御コード | 説明 |
---|---|
|
デバイス イベントをサービスに通知します。 ( RegisterDeviceNotification 関数を使用してこれらの通知を受信するには、サービスが登録されている必要があります)。 dwEventType パラメーターと lpEventData パラメーターには、追加情報が含まれています。 |
|
コンピューターのハードウェア プロファイルが変更されたことをサービスに通知します。 dwEventType パラメーターには追加情報が含まれています。 |
|
システム電源イベントをサービスに通知します。 dwEventType パラメーターには追加情報が含まれています。 dwEventType がPBT_POWERSETTINGCHANGE場合、lpEventData パラメーターにも追加情報が含まれます。 |
|
セッション変更イベントをサービスに通知します。 サービスは、ログオンが試行される前に完全に読み込まれた場合にのみ、ユーザー ログオンの通知を受け取ります。 dwEventType パラメーターと lpEventData パラメーターには、追加情報が含まれています。 |
|
システム時刻が変更されたことをサービスに通知します。 lpEventData パラメーターには追加情報が含まれています。 dwEventType パラメーターは使用されません。
Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: このコントロール コードはサポートされていません。 |
|
イベントが発生したことをサービス トリガー イベント に登録されたサービスに通知します。
Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: このコントロール コードはサポートされていません。 |
|
ユーザーが再起動を開始したことをサービスに通知します。
Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: このコントロール コードはサポートされていません。 |
このパラメーターは、次の表で説明するように、ユーザー定義のコントロール コードにすることもできます。
制御コード | 意味 |
---|---|
|
サービスは、コントロール コードに関連付けられているアクションを定義します。 |
[in] dwEventType
発生したイベントの種類。 このパラメーターは、 dwControl が SERVICE_CONTROL_DEVICEEVENT、SERVICE_CONTROL_HARDWAREPROFILECHANGE、 SERVICE_CONTROL_POWEREVENT、または SERVICE_CONTROL_SESSIONCHANGEの場合に使用 されます。 それ以外の場合は 0 です。
dwControl がSERVICE_CONTROL_DEVICEEVENT場合、このパラメーターには次のいずれかの値を指定できます。
- DBT_DEVICEARRIVAL
- DBT_DEVICEREMOVECOMPLETE
- DBT_DEVICEQUERYREMOVE
- DBT_DEVICEQUERYREMOVEFAILED
- DBT_DEVICEREMOVEPENDING
- DBT_CUSTOMEVENT
dwControl がSERVICE_CONTROL_SESSIONCHANGE場合、このパラメーターは、WM_WTSSESSION_CHANGE メッセージの wParam パラメーターで指定された値のいずれかになります。
[in] lpEventData
必要に応じて、追加のデバイス情報。 このデータの形式は、 dwControl パラメーターと dwEventType パラメーターの値によって異なります。
dwControl がSERVICE_CONTROL_DEVICEEVENTの場合、このデータは、アプリケーションがWM_DEVICECHANGE メッセージの一部として受け取る lParam パラメーターに対応します。
dwControl がSERVICE_CONTROL_POWEREVENTで、dwEventType がPBT_POWERSETTINGCHANGE場合、このデータはPOWERBROADCAST_SETTING構造体へのポインターです。
dwControl がSERVICE_CONTROL_SESSIONCHANGE場合、このパラメーターはWTSSESSION_NOTIFICATION構造体へのポインターです。
dwControl がSERVICE_CONTROL_TIMECHANGE場合、このデータはSERVICE_TIMECHANGE_INFO構造体へのポインターです。
[in] lpContext
RegisterServiceCtrlHandlerEx から渡されるユーザー定義データ。 複数のサービスが 1 つのプロセスを共有する場合、 lpContext パラメーターはサービスの識別に役立ちます。
戻り値
この関数の戻り値は、受信したコントロール コードによって異なります。
次の一覧は、この戻り値の規則を示しています。
- 一般に、サービスがコントロールを処理しない場合は、 ERROR_CALL_NOT_IMPLEMENTEDを返します。 ただし、サービスが処理しない場合でも、サービスはSERVICE_CONTROL_INTERROGATEのNO_ERRORを返す必要があります。
- サービスがSERVICE_CONTROL_STOPまたは SERVICE_CONTROL_SHUTDOWN を処理 する場合は、 NO_ERRORを返します。
- サービスが SERVICE_CONTROL_DEVICEEVENT処理する場合は、 NO_ERROR を返して要求を許可し、要求を拒否するエラー コードを返します。
- サービス がSERVICE_CONTROL_HARDWAREPROFILECHANGE処理する場合は、 NO_ERROR を返して要求を許可し、要求を拒否するエラー コードを返します。
- サービス がSERVICE_CONTROL_POWEREVENT処理する場合は、 NO_ERROR を返して要求を許可し、要求を拒否するエラー コードを返します。
- サービスが処理するその他のすべてのコントロール コードについては、 NO_ERRORを返します。
注釈
サービスが開始されると、 ServiceMain 関数は RegisterServiceCtrlHandlerEx 関数を直ちに呼び出して、制御要求を処理する HandlerEx 関数を指定する必要があります。 受け入れるコントロール コードを指定するには、 SetServiceStatus 関数と RegisterDeviceNotification 関数を使用します。
サービスのメイン スレッド内のコントロール ディスパッチャーは、サービス コントロール マネージャーからコントロール要求を受信するたびに、指定されたサービスのコントロール ハンドラー関数を呼び出します。 コントロール要求を処理した後、サービスの状態が変更され、新しい状態がサービス コントロール マネージャーに報告される場合、コントロール ハンドラーは SetServiceStatus を呼び出す必要があります。
コントロール ハンドラー関数は、通知を受信してすぐに返すことを目的としています。 コールバック関数は、そのパラメーターを保存し、追加の作業を実行するために他のスレッドを作成する必要があります。 (アプリケーションでは、サービスを停止する前に、このようなスレッドが終了していることを確認する必要があります)。特に、コントロール ハンドラーでは、デッドロックが発生したり、システムが応答を停止したりする可能性があるため、ロックの取得など、ブロックする可能性のある操作を回避する必要があります。
サービス コントロール マネージャーは、コントロール コードをサービスに送信すると、ハンドラー関数が返されるのを待ってから、他のサービスに追加のコントロール コードを送信します。 コントロール ハンドラーは、可能な限り迅速にを返す必要があります。30 秒以内にが返されない場合、SCM はエラーを返します。 サービスがコントロール ハンドラーの実行時に長い処理を行う必要がある場合は、長い処理を実行するセカンダリ スレッドを作成してから、コントロール ハンドラーから戻る必要があります。 これにより、サービスがコントロール ディスパッチャーを接続し、他のサービスが制御コードを受信するのをブロックできなくなります。
SERVICE_CONTROL_SHUTDOWN制御コードは、サービスのシャットダウンに使用できる時間 (約 20 秒) が限られているため、シャットダウン中に絶対にクリーンする必要があるサービスによってのみ処理する必要があります。 この時間が経過すると、サービスのシャットダウンが完了したかどうかに関係なく、システムのシャットダウンが続行されます。 システムがシャットダウン状態のまま (再起動または電源オフではない) 場合、サービスは引き続き実行されることに注意してください。 サービスが SERVICE_CONTROL_SHUTDOWNを受け入れるように登録する場合は、コントロール コードを処理し、 NO_ERRORを返す必要があります。 この制御コードのエラーを返し、タイムリーに停止しないと、システムのシャットダウンに必要な時間が長くなる可能性があります。システムは、システムのシャットダウンを続行する前に、サービスのシャットダウンに許容される完全な時間を待機する必要があるためです。
サービスのクリーンにより多くの時間が必要な場合は、待機ヒントと共にSTOP_PENDINGステータス メッセージを送信する必要があるため、サービス コントローラーは、サービスのシャットダウンが完了したことをシステムに報告するまでの待機時間を把握します。 ただし、サービスがシャットダウンを停止しないようにするには、サービス コントローラーが待機する時間に制限があります。 サービス スナップインを介してサービスがシャットダウンされている場合、制限は 125 秒です。 オペレーティング システムが再起動中の場合、次のレジストリ キーの WaitToKillServiceTimeout 値に制限時間が指定されます。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
プラグ アンド プレイデバイス イベントはできるだけ早く処理してください。そうしないと、システムが応答しなくなる可能性があります。 イベント ハンドラーが実行をブロックする可能性がある操作 (I/O など) を実行する場合は、別のスレッドを起動して操作を非同期的に実行することをお勧めします。
また、サービスは SetConsoleCtrlHandler 関数を使用してシャットダウン通知を受け取ることもできます。 この通知は、実行中のアプリケーションがシャットダウンされるときに受信されます。これは、サービスがシャットダウンされる前に発生します。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP (デスクトップ アプリのみ) |
サポートされている最小のサーバー | Windows Server 2003 (デスクトップ アプリのみ) |
対象プラットフォーム | Windows |
ヘッダー | winsvc.h (Windows.h を含む) |