Windowsがスリープ状態または休止状態に移行または終了するときに発生するWindowsイベントをサブスクライブすることは可能ですか?
クリーンアップを実行し、スリープが解除されたときのタイミングの問題を回避するために、コンピューターがスリープするタイミングをアプリケーションに認識させる必要があります。
Windowsがスリープ状態または休止状態に移行または終了するときに発生するWindowsイベントをサブスクライブすることは可能ですか?
クリーンアップを実行し、スリープが解除されたときのタイミングの問題を回避するために、コンピューターがスリープするタイミングをアプリケーションに認識させる必要があります。
Microsoft.Win32.SystemEvents.PowerModeChanged
イベントは、この情報を提供します。このイベントは、Microsoft がこれまでにリリースした .NET フレームワークのすべてのバリアントで利用できます。
.NET では、PowerModeChangedイベントを使用します。Win32 では、WM_POWERBROADCASTメッセージを使用します。
Visual Studio 2005 C++ MFC アプリケーションでは、次の例のように、メッセージON_MESSAGE()
を探してメッセージ マップにを追加する必要があります。WM_POWERBROADCAST
BEGIN_MESSAGE_MAP(CFrameworkWndDoc, CWindowDocument)
//{{AFX_MSG_MAP(CFrameworkWndDoc)
ON_WM_CHAR()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_POWERBROADCAST, OnPowerMsgRcvd)
END_MESSAGE_MAP()
次に、クラス定義の変更と共にメッセージ ハンドラー関数を追加して、メッセージ ハンドラーのメンバー関数を宣言し、wParam
次のスケルトンのようにメッセージ タイプの変数を確認できるようにする必要があります。
// Handle the WM_POWERBROADCAST message to process a message concerning power management
// such as going to Sleep or Waking Up.
LRESULT CFrameworkWndDoc::OnPowerMsgRcvd(WPARAM wParam, LPARAM lParam)
{
switch (wParam) {
case PBT_APMPOWERSTATUSCHANGE:
TRACE0("PBT_APMPOWERSTATUSCHANGE received\n");
break;
case PBT_APMRESUMEAUTOMATIC:
TRACE0("PBT_APMRESUMEAUTOMATIC received\n");
break;
case PBT_APMRESUMESUSPEND:
TRACE0("PBT_APMRESUMESUSPEND received\n");
break;
case PBT_APMSUSPEND:
TRACE0("PBT_APMSUSPEND received\n");
break;
}
return 0;
}
私が見たのは、デバッガーで起動された Windows 7 で実行されているアプリケーションで上記を使用したテストで、アプリケーションを実行している PC を手動でスリープ状態にすると、次のメッセージが表示されることです。
PBT_APMSUSPEND received
その後、PC を再起動してサインインすると、デバッガーの出力ウィンドウに次の 2 つのメッセージが次々に表示されます。
PBT_APMRESUMESUSPEND received
PBT_APMRESUMEAUTOMATIC received
私がこれまでに見つけたすべてのことは、あなたがスリープ状態から抜け出そうとしているのか休止状態から抜け出そうとしているのかわからないことを示しています。ファイルとデバイスのハンドルに関しては、中断時または再開時に何をする必要があるかについて、さらに調査を続けています。再開後、COM ポートへのファイル ハンドルが無効になっている兆候を確認しました。また、インスタンス データベース接続用の他のプロセスへのインターフェイスについてもよくわかりません。
標準のスリープおよび休止状態の電源管理状態に加えて、Microsoft はWindows 8 および 8.1でコネクト スタンバイ電源状態を導入しました。
通常、デスクトップ アプリケーションは、コネクト スタンバイと統合するために追加の作業を必要としません。
Desktop Activity Moderator (DAM) は、すべてのデスクトップ アプリケーションを一時停止し、コネクト スタンバイ中にサード パーティ システム サービスの実行時間を調整する Windows コンポーネントです。DAM の目的は、既存のアプリケーションやサービスとの基本的なソフトウェアの互換性を維持しながら、スリープ中のバッテリ寿命への影響を軽減することです。
Windows は、DAM フェーズが完了した後、コネクト スタンバイのどの部分でもデスクトップ アプリケーションが実行されないようにします。Windows では、DAM フェーズの完了後に、サード パーティのシステム サービスを調整モードで実行できます。このモードでは、サードパーティ サービスは、30 秒ごとの実時間で 1 秒しか実行できません。
Intelの Lynn Merrill による The Art of Graceful Application Suspension には、Windows での電源管理に関連するさまざまな Windows メッセージ タイプの処理に関する情報が記載されていますが、日付は 2005 年であるため、すべての資料が Windows XP 以降の Windows に関連しているわけではありません。このドキュメントで説明されているメッセージ シーケンスには、使用されなくなったメッセージが少なくとも 1 つあります。Windows Vista 以降でPBT_APMQUERYSUSPEND
は、アプリケーションが中断できたかどうかを要求するために使用されたメッセージは、Windows では使用されなくなりました。このSetThreadExecutionState()
関数は、スリープまたは休止状態への変更によってスレッドを中断できないことを示すために使用されるようになりました。電源管理状態メッセージの変更の詳細については、stackoverflow Can't catch sleep suspend messages (winxp)の回答を参照してください。
Windows XP 以降のシステム電源状態イベント
Microsoft は、Windows OS のさまざまなバージョンがより多くのコンポーネントを共有するため、Windows XP 以降、電源管理を改善しました。Windows のバージョンは現在、より慎重な電源管理を必要とするバッテリを備えた小型デバイスに展開されています。電源イベントへの登録を参照してください。RegisterPowerSettingNotification()
関数と関数の両方がありUnregisterPowerSettingNotification()
ます。
アプリケーションまたはサービスは、
RegisterPowerSettingNotification
関数を使用して通知を登録します。対応する電源設定が変更されると、システムは次のように通知を送信します。
- アプリケーションは、構造体を指す とを含む
WM_POWERBROADCAST
メッセージを受け取ります。wParam
PBT_POWERSETTINGCHANGE
lParam
POWERBROADCAST_SETTING
- サービスは、
HandlerEx
関数を呼び出すことによって、登録したコールバック関数への呼び出しを受け取りRegisterServiceCtrlHandlerEx
ます。コールバック関数に送信されるlpEventData
パラメーターは、構造体HandlerEx
を指しています。POWERBROADCAST_SETTING
この
POWERBROADCAST_SETTING
構造体では、PowerSetting
メンバーには通知を識別する GUID が含まれ、データ メンバーには電源設定の新しい値が含まれます。
Windows Vista 以降の Windows API の電源管理関数の一覧については、電源管理関数も参照してください。
システムの電源ステータスとバッテリーの状態
Windows システム サービス API 関数GetSystemPowerStatus()
を使用して、現在の電源状態を取得できます。
システムの電源ステータスを取得します。ステータスは、システムが AC 電源または DC 電源で動作しているかどうか、現在バッテリーが充電中かどうか、バッテリーの寿命がどれくらい残っているか、バッテリー セーバーがオンかオフかを示します。
ただし、SYSTEM_POWER_STATUS
構造体で返される情報は、バッテリーの状態と AC/DC 電源に関するものであり、 Sleep や Hibernate などの実際のデバイスの電源状態ではないことに注意してください。
また、Windows デバイスがスリープ状態または休止状態にある場合、アプリケーションは実行されないため、この関数を使用して現在の Windows の電源状態を判断することはできません。このトピックの調査中にこの投稿にたどり着いた人にとって役立つ可能性があるため、このメモを含めます。
Win32_PowerManagementEvent WMI イベントを監視できます
これを監視する頻度はわかりませんが、.NET でサービスを作成する場合は、ServiceBase をオーバーライドし、CanHandlePowerEvent を true に設定すると、PowerBroadcastStatus 列挙を介して電力の変化が通知されます。
NetworkChange.NetworkAvailabilityChanged および NetworkChange.NetworkAddressChanged にサブスクライブできます。
私は通常、2 秒のタイマーを開始して、タイムアウトになったときにスリープ モードになった後にネットワーク通信を再開できるようにします。