スリープ抑止C#版

2017年9月30日

丸写しではあるけど、一度動作させてみます。

元はこちらなんですけど、このままじゃ動かなくて、ハマったので・・・。

http://variedtastefinder.jp/blog/?p=1567

 

まず
using System.Runtime.InteropServices;

が必要で、これを入れないとDllImportでエラーになってしまいます。

また暗転防止でSetThreadExecutionStateを使っているのですが宣言がありません。

[DllImport(“kernel32.dll")]
extern static ExecutionState SetThreadExecutionState(ExecutionState esFlags);

このように書くことでOKでした。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace c_nosleep{
  public partial class MainForm : Form{
    [FlagsAttribute]
    public enum ExecutionState : uint{
        // 関数が失敗した時の戻り値
        Null = 0,
        // スタンバイを抑止
        SystemRequired = 1,
        // 画面OFFを抑止
        DisplayRequired = 2,
        // 効果を永続させる。ほかオプションと併用する。
        Continuous = 0x80000000,
    }
    [DllImport("kernel32.dll")]
    extern static ExecutionState SetThreadExecutionState(ExecutionState esFlags);
    [DllImport("user32.dll")]
    extern static uint SendInput(
        uint nInputs,   // INPUT 構造体の数(イベント数)
        INPUT[] pInputs,   // INPUT 構造体
        int cbSize     // INPUT 構造体のサイズ
    );
    [StructLayout(LayoutKind.Sequential)]
        struct INPUT{
            public int type;  // 0 = INPUT_MOUSE(デフォルト), 1 = INPUT_KEYBOARD
            public MOUSEINPUT mi;
        }
    [StructLayout(LayoutKind.Sequential)]
        struct MOUSEINPUT{
            public int dx;
            public int dy;
            public int mouseData;  // amount of wheel movement
            public int dwFlags;
            public int time;  // time stamp for the event
            public IntPtr dwExtraInfo;
        }

    // dwFlags
    const int MOUSEEVENTF_MOVED = 0x0001;
    const int MOUSEEVENTF_LEFTDOWN = 0x0002;  // 左ボタン Down
    const int MOUSEEVENTF_LEFTUP = 0x0004;  // 左ボタン Up
    const int MOUSEEVENTF_RIGHTDOWN = 0x0008;  // 右ボタン Down
    const int MOUSEEVENTF_RIGHTUP = 0x0010;  // 右ボタン Up
    const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;  // 中ボタン Down
    const int MOUSEEVENTF_MIDDLEUP = 0x0040;  // 中ボタン Up
    const int MOUSEEVENTF_WHEEL = 0x0080;
    const int MOUSEEVENTF_XDOWN = 0x0100;
    const int MOUSEEVENTF_XUP = 0x0200;
    const int MOUSEEVENTF_ABSOLUTE = 0x8000;
    const int screen_length = 0x10000;  // for MOUSEEVENTF_ABSOLUTE (この値は固定)

    public MainForm(){
        InitializeComponent();
    }

    void Timer1Tick(object sender, EventArgs e){
        //画面暗転阻止
        SetThreadExecutionState(ExecutionState.DisplayRequired);
        // ドラッグ操作の準備 (struct 配列の宣言)
        INPUT[] input = new INPUT[1];  // イベントを格納
        // ドラッグ操作の準備 (イベントの定義 = 相対座標へ移動)
        input[0].mi.dx = 0;  // 相対座標で0 つまり動かさない
        input[0].mi.dy = 0;  // 相対座標で0 つまり動かさない
        input[0].mi.dwFlags = MOUSEEVENTF_MOVED;
        // ドラッグ操作の実行 (イベントの生成)
        SendInput(1, input, Marshal.SizeOf(input[0]));
    }
  }
}

 

これを実行している間は自動スリープにはならないことを確認しました。

ところが操作してスリープを実行した際には流石にスリープしてしまいます。
これも拒否できたらすごかったのですが・・・。
でもちょっと考えてみたいですね。