Windowsアプリ動作中スタンバイ防止、ディスプレイオフ(SetThreadExecutionState、SC_MONITORPOWER)

2018年11月23日
Windowsアプリが動いている間、Windowsがスタンバイ状態にならないようにしつつ、ディスプレイをオフにしたくて、やってみたメモです。

調べてみたら割とすぐ出てきたので、わざわざメモするほどではないかもしれないけど。
C#で作っていますが、Windows APIを呼ぶだけなので、どの言語でも実現方法は同じです。

スタンバイになるとアプリが止まっちゃうので、それを防ぎたいのと、夜の寝てる間に動かしたいけどディスプレイがまぶしいので、オフにしたい、という目的です。

スポンサーサイト

目次


 1.スタンバイ防止のやり方 SetThreadExecutionState
 2.ディスプレイをオフにするやり方 WM_SYSCOMMANDのSC_MONITORPOWER
 3.スタンバイ防止してディスプレイをオフにする例

1.スタンバイ防止のやり方 SetThreadExecutionState


スタンバイ防止は、Windows APIのSetThreadExecutionStateで設定できます。

APIの仕様


SetThreadExecutionState function | Microsoft Docs
に書いてある通り、スタンバイ防止にはES_SYSTEM_REQUIRED とES_CONTINUOUSを引数に設定してSetThreadExecutionStateを呼び出せば良いです。

これをそのままC#で呼び出すようにしたクラス


    public static class ExecutionState
{
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

[FlagsAttribute]
public enum EXECUTION_STATE : uint
{
// スタンバイ状態にするのを防ぐ
ES_SYSTEM_REQUIRED = 0x00000001,

// ディスプレイをオフにするのを防ぐ
ES_DISPLAY_REQUIRED = 0x00000002,

// 実行状態を維持する
ES_CONTINUOUS = 0x80000000,
}

// スタンバイ防止
public static EXECUTION_STATE DisableSuspend()
{
return SetThreadExecutionState(
EXECUTION_STATE.ES_SYSTEM_REQUIRED |
EXECUTION_STATE.ES_CONTINUOUS);
}

// スタンバイ防止を解除
public static EXECUTION_STATE EnableSuspend()
{
return SetThreadExecutionState(
EXECUTION_STATE.ES_CONTINUOUS);
}
}

使うとき


スタンバイ防止する
ExecutionState.DisableSuspend();

スタンバイ防止を解除する
ExecutionState.EnableSuspend();

2.ディスプレイをオフにするやり方 WM_SYSCOMMANDのSC_MONITORPOWER


WindowsメッセージのWM_SYSCOMMANDで実現できます。
WM_SYSCOMMAND message | Microsoft Docs
このメッセージのlParamが、SC_MONITORPOWERです。

これを適当に実装したクラス


    public static class Display
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr SendMessage(int hWnd, uint Msg, int wParam, int lParam);

private const uint WM_SYSCOMMAND = 0x0112;
private const int SC_MONITORPOWER = 0xF170;

public static void PowerOff()
{
SendMessage(-1, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
}

public static void PowerOn()
{
SendMessage(-1, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
}
}

使うとき


ディスプレイをオフにする
Display.PowerOff();
マウスを動かしたりしたら、ディスプレイがオンになります。

3.スタンバイ防止してディスプレイをオフにする例


    private void button1_Click(object sender, EventArgs e)
ExecutionState.DisableSuspend();
Thread.Sleep(1000); // 1秒待ってから
Display.PowerOff();
}

途中1秒待ってるのは、マウスをクリックしてすぐにディスプレイオフにすると、マウスから手を放すときにちょっとマウスが動いてしまって、すぐディスプレイがオンになってしまいがちなので、それを防止するためです。

私のWindows10のPCでは、今のところ正常に動いています。


スポンサーサイト

posted at 14:34 | Comment(0) | プログラミング
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: