質問者
電源状態がサスペンドになった後で、サスペンドを解除する

質問
-
お世話になっております。北窓舎の芦田と申します。
特定のアプリが起動しているときに、サスペンド状態を無効にしたいと思っています。
電源モードがサスペンドになった後で、それを解除する(サスペンド状態ではなくする)方法をお教えください。
コードでは、電源モードが変化したらプロセスを取得し特定のアプリが起動しているかを判断し、
起動していればサスペンドを無効に(レジューム状態に)したいと思っているのですが、サスペンド状態を解除することができません。
現在のコードは次のとおりです。
Private Sub SystemEvents_PowerModeChanged _ (ByVal sender As Object, ByVal e As Microsoft.Win32.PowerModeChangedEventArgs) ' --- Dim previousExecutionState As Long = 0D ' --- PowerMode(電源モード:Suspend/Resume) Select Case e.Mode Case Is = Microsoft.Win32.PowerModes.Suspend ' --- ▼ サスペンド状態になった Call cls_DGV.prc_Get_Process() ' -- プロセスを取得(dgv_Process に格納) Call cls_DGV.prc_Check_AppRunning() ' -- 指定ソフトのプロセスが起動中かをチェック If (cls_DGV.IsAppRunning) Then ' --★★ 指定プロセスが起動中ならサスペンド禁止 ★★ Me.DisplayHowToClose = False ' -- frm_HowToClose を表示しない SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or EXECUTION_STATE.ES_CONTINUOUS) Me.PowerStatus = "prohigit from Suspending" Call cls_FileIO.prc_Write_LogFile(Me.PowerStatus) ' --■ Power.log ファイルを書き出す End If Case Is = Microsoft.Win32.PowerModes.Resume ' --- ▼ サスペンドから復帰した Me.PowerStatus = "Resume from Suspend/Sleep" Call cls_FileIO.prc_Write_LogFile(Me.PowerStatus) ' --■ Power.log ファイルを書き出す Me.DisplayHowToClose = True ' -- frm_HowToClose を表示する End Select End Sub ' --- スリープモードを抑止にする. Private Function DisableSleepMode() As Long Return SetThreadExecutionState(EXECUTION_STATE.ES_SYSTEM_REQUIRED Or EXECUTION_STATE.ES_CONTINUOUS) End Function ' --- Private Enum EXECUTION_STATE As Integer ES_SYSTEM_REQUIRED = &H1 ES_DISPLAY_REQUIRED = &H2 ES_USER_PRESENT = &H4 ES_CONTINUOUS = &H80000000 End Enum ' --- Private Declare Auto Function _ SetThreadExecutionState Lib "kernel32.dll" (ByVal esFlags As Long) As Long
皆さまのお知恵を拝借できれば幸いです。
Ashidacchi
すべての返信
-
本来はサスペンドへの遷移自体を禁止したいが、それができないので、次善の策としてサスペンドからの自動復帰ということにしたい、って感じでしょうかね?
Waitable Timerを使えばサスペンドからの復帰ができるはずです。スレッドの扱いが面倒だった記憶がありますが。
ただし、電源オプションの「スリープ解除タイマーの許可」によってユーザ側が禁止することもできたはず。
// Win10では許可のところに重要なやつだけ認めるという項目が増えてるけど、CreateWaitableTimer(Ex)にそれっぽいフラグがあるわけでもないし、なんか別の方法が増えたのかしらん?
-
Hongliang さん、
リプライしていただき、ありがとうございます。
どんな場合にでも(常に)サスペンドへの遷移を禁止したいというわけではなく、特定のソフトが起動中の場合だけサスペンドへの遷移を禁止したいと思っています。
Timer により常にプロセスを取得して、特定のプロセスが起動中ならサスペンド禁止にする方法も考えてみましたが、常にプロセスを取得する(例えば 1,000 mSec ごとにプロセスを取得する)のも無駄な気がしたので、サスペンド状態になった時だけプロセスを取得し(特定のプロセスが起動中なら)サスペンドを解除したいと思った次第です。
プラットフォームとしては、Windows 7, 8.1, および 10 を想定しています。
Waitable Timer については知らなかったので、調べてみます。
取り急ぎ、お礼と背景説明まで。Ashidacchi
-
-
根本的なことですが、質問者さんのいう「サスペンド」が何であるかを明確に把握できていますでしょうか?
Windowsは常に機能追加されていて、モダンスタンバイ(was Instant Go or コネクトスタンバイ)に対応している機種もあります。プログラム的に「サスペンド」対策を行っていても、そもそも「サスペンド」されておらずモダンスタンバイなどが動作していた、ということはないでしょうか?
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年8月17日 8:35
-
サスペンド、スタンバイ、スリープ等呼び方はいろいろありますが、CPUを停止させるS1以上のステートが大前提にあります。対してモダンスタンバイはCPUを停止させないS0 low-power idleであり、概念が全く異なります。
質問者さんとしては、この新しい概念に対してどのような動作を期待するのかを説明するのが先であり、「電源状態がサスペンドになった後で、サスペンドを解除する」の延長で議論すべき話題ではないと考えます。
また、質問の前提条件であるはずの「サスペンドが何であるか把握できているか」の確認を無視しておきながら、追加質問する態度は回答者を侮辱するものだとは思わないのでしょうか。なお、本スレッドについてのコメントとしては、SetThreadExecutionState(ES_SYSTEM_REQUIRED|ES_CONTINUOUS)の代わりにSetThreadExecutionState(ES_DISPLAY_REQUIRED|ES_CONTINUOUS)を使用した場合はどのような挙動になるでしょうか? もしくはSetThreadExecutionState(ES_SYSTEM_REQUIRED|ES_DISPLAY_REQUIRED|ES_CONTINUOUS)も。ディスプレイを表示するためにはシステムを停止できないためモダンスタンバイも含め省電力モードに入らなくなる可能性があるためです。
-
サスペンド、スタンバイ、スリープ等呼び方はいろいろありますが、CPUを停止させるS1以上のステートが大前提にあります。対してモダンスタンバイはCPUを停止させないS0 low-power idleであり、概念が全く異なります。
質問者さんとしては、この新しい概念に対してどのような動作を期待するのかを説明するのが先であり、「電源状態がサスペンドになった後で、サスペンドを解除する」の延長で議論すべき話題ではないと考えます。
また、質問の前提条件であるはずの「サスペンドが何であるか把握できているか」の確認を無視しておきながら、追加質問する態度は回答者を侮辱するものだとは思わないのでしょうか。なお、本スレッドについてのコメントとしては、SetThreadExecutionState(ES_SYSTEM_REQUIRED|ES_CONTINUOUS)の代わりにSetThreadExecutionState(ES_DISPLAY_REQUIRED|ES_CONTINUOUS)を使用した場合はどのような挙動になるでしょうか? もしくはSetThreadExecutionState(ES_SYSTEM_REQUIRED|ES_DISPLAY_REQUIRED|ES_CONTINUOUS)も。ディスプレイを表示するためにはシステムを停止できないためモダンスタンバイも含め省電力モードに入らなくなる可能性があるためです。
ご質問(ご確認)を無視したつもりではありません。知らなかったので慌てて調べた結果、System Power State が関わっているらしいと思い(誤解しているかも知れませんが)、System Power State について質問しました。その際に、知らなかったとの返答を失念したのは私のミスです。が、繰り返しますが、無視したつもりではありません。
また、「本スレッドについてのコメントとしては・・・」に回答しないと、お叱りを受けるのでしょうか?
スレッドを立てて(7/24)から日数を経ており、ソースコードは大きく変えていますが、それでも挙動確認しないと侮辱したとお感じになるのでしょうか?Ashidacchi