サービス

マウスを自動で移動させてスリープさせないアプリ(SoulMouse)

離席中でもWindowsをスリープさせたくない

体は離席しても、魂だけは在席してマウス操作しててほしい。

というわけで、プログラムでマウス操作させてみました。

作ったアプリ

  • カーソル移動 → スクロール → 待ち、を繰り返すアプリ
  • それぞれの時間はランダム(配布版では「待ち」時間はもう少し長め)
  • 人がいなくても、人のぬくもりを感じるアプリになりました

アプリを使用してみる

  1. 以下からダウンロード
  2. zip を展開
  3. SoulMouse.exe を実行するとタスクトレイに登場(灰色矢印アイコン)
  4. 「CTRL + SHIT + S」で開始(カーソルが自動で動き出す)
  5. 「CTRL + SHIT + D」で停止
  6. タスクトレイのアイコンを右クリック「終了」でタスクトレイから削除
墾田
よくPCスリープになってしまう人は是非。
テレワーク監視はスリープ時間チェックから行われることが多い模様。
Webカメラを定期送信するなどの本気の監視には対応できないですが。
いずれにせよ、用法用量を守って正しくお使いください。

ソースコード解説

マウスをぷるぷる動かしてスクリーンセーバを抑制するアプリ を参考にさせていただきました。ありがとうございます。

上記ページのソースコードに、以下を追加しています。
(Wait, Move, Wheel のステート追加)

const int MOUSEEVENTF_WHEEL = 0x800;
INPUT[] mInput = new INPUT[1];
Stopwatch mStopwatch = new Stopwatch();
enum EState { Wait, Move, Wheel }
EState mState = EState.Wait;
Random mRandom = new Random();
int mTargetX = 0, mTargetY = 0;


private async void autoMouseRunStart()
{
    isAppRun = true;
    int screen_width = Screen.PrimaryScreen.Bounds.Width;
    int screen_height = Screen.PrimaryScreen.Bounds.Height;
    mStopwatch.Restart();
    mInput[0].mi.dx = Cursor.Position.X * (65535 / screen_width);
    mInput[0].mi.dy = Cursor.Position.Y * (65535 / screen_height);
    mInput[0].mi.dwFlags = MOUSEEVENTF_MOVED | MOUSEEVENTF_ABSOLUTE;

    // 開始時点でマウスがPrimaryScreenに無い場合、PrimaryScreenに強制移動させる
    if (Cursor.Position.X > screen_width || Cursor.Position.Y > screen_height)
    {
        mInput[0].mi.dx = (screen_width / 2) * (65535 / screen_width);
        mInput[0].mi.dy = (screen_height / 2) * (65535 / screen_height);
        SendInput(1, mInput, Marshal.SizeOf(mInput[0]));
    }

    await Task.Run(() =>
    {
        while (isAppRun)
        {
            switch (mState)
            {
            case EState.Wait:
                // 一定時間経過したら EState.Move に移行
                if (mStopwatch.ElapsedMilliseconds > mWaitTime)
                {
                    mState = EState.Move;
                    mMoveTime = mRandom.Next(1000, 3000); // 1~3秒でマウス移動
                    mTargetX = mRandom.Next(0, screen_width);  // ランダムなX座標
                    mTargetY = mRandom.Next(0, screen_height); // ランダムなY座標
                    mInput[0].mi.dwFlags = MOUSEEVENTF_MOVED | MOUSEEVENTF_ABSOLUTE;
                    mStopwatch.Restart();
                }

                // 適当にスリープさせる
                // さもないと、CPU100%で処理してしまう
                System.Threading.Thread.Sleep(5);
                break;

            case EState.Move:
                // 一定時間経過したら EState.Wheel に移行
                if (mStopwatch.ElapsedMilliseconds > mMoveTime)
                {
                    mState = EState.Wheel;
                    mWheelTime = mRandom.Next(100, 800); // 0.1~0.8秒でマウスホイール
                    mInput[0].mi.dwFlags = MOUSEEVENTF_WHEEL;
                    mInput[0].mi.mouseData = mRandom.Next(-1, 2);
                    mStopwatch.Restart();
                }

                // カーソルを目標に追従させる
                mInput[0].mi.dx += (int)((mTargetX - Cursor.Position.X) * 0.07) * (65535 / screen_width);
                mInput[0].mi.dy += (int)((mTargetY - Cursor.Position.Y) * 0.07) * (65535 / screen_height);

                // 適当にスリープさせる
                // さもないと、カーソル移動処理が実行されすぎて移動が速くなりすぎてしまう
                System.Threading.Thread.Sleep(5);

                break;

            case EState.Wheel:
                // 一定時間経過したら EState.Wait に移行
                if (mStopwatch.ElapsedMilliseconds > mWheelTime)
                {
                    mState = EState.Wait;
                    mWaitTime = mRandom.Next(10000, 30000); // 10~300秒でマウス停止
                    mInput[0].mi.dwFlags = 0;
                    mStopwatch.Restart();
                }

                // マウスホイールではスリープさせない
                // スリープさせると滑らかなスクロールにならなかった
                //System.Threading.Thread.Sleep(1);

                break;
            }

            // イベントの実行
            // Cursor.Position への代入や、SetCursorPos での座標セットではスリープ状態になってしまうので SendInput を使用
            SendInput(1, mInput, Marshal.SizeOf(mInput[0]));
        }
    });
}

// 機能停止
private void autoMouseRunStop()
{
    isAppRun = false;
    mState = EState.Wait;
    mTargetX = mTargetY = 0;
    mWaitTime = mMoveTime = mWheelTime = 2000;
}

 

マウスホイール時に Thread.Sleep するとスクロールがガクガクしていました。
よって、EState.Wheel では Thread.Sleep していません。
CPU速度に依存するコードになっているので、高性能PCでは Thread.Sleep する必要があるかもしれません。

プロジェクトは以下に置いてあります。

GitHub/SoulMouse

-サービス

© 2022 墾田ええねん! Powered by AFFINGER5