Windows スクリーンセーバーが起動しないようにするための推奨される方法はありますか? 私が見つけた最も近いものはこの記事ですが、私が本当にやりたいことは、現在設定されているスクリーンセーバーの値をだますのではなく、コンピューターがアイドル状態ではないことを Windows に伝えることです。
14 に答える
テストのために、スクリーンセーバーを 1 分に設定し、パスワードを要求しました。
SC_SCREENSAVE をキャプチャして、VB .Net で -1 を返そうとしました。コメントされているように、スクリーンセーバーのパスワードがない場合は機能しますが、スクリーンセーバーのパスワードがアクティブな場合は失敗します。(Windows XPで試しました)。また、これを 1000 ミリ秒ごとにタイマーの tick イベントに入れます。
Static dir As Integer = 4
Cursor.Position = Cursor.Position + New Size(dir, dir)
dir = -dir
うまくいきません。カーソルが前後に揺れ、1 分後にスクリーンセーバーが一瞬点滅してからオフになります。スクリーンセーバーがオンになるのは一瞬だけで、パスワードを要求するほど長くはありません。しかし、それでもフラッシュは醜いです。
次に、user32.dll の SetCursorPos と GetCursorPos を使用してみました。pinvoke で調べることができます。上記と同じ結果です。
次に、この質問の他の場所で言及されている「JiggleMouse」のコードをのぞきました。JiggleMouse は SendInput を使用します。 SendInput が機能します。 スクリーンセーバーのフラッシュはありません。50 秒ごとにトリガーされる Timer 内に SendInput への呼び出しを配置しました (スクリーンセーバーの最小タイムアウトである 60 秒未満)。マウスを 0,0 のデルタだけ動かすだけで十分です。実際の動きはありません。それはうまくいきます。Tick イベントに入れるコード:
Dim i(0) As INPUT
i(0).dwType = INPUT.InputType.INPUT_MOUSE
i(0).mkhi = New MOUSEKEYBDHARDWAREINPUT
i(0).mkhi.mi = New MOUSEINPUT
i(0).mkhi.mi.dx = 0
i(0).mkhi.mi.dy = 0
i(0).mkhi.mi.mouseData = 0
i(0).mkhi.mi.dwFlags = MOUSEINPUT.MouseEventFlags.MOUSEEVENTF_MOVE
i(0).mkhi.mi.time = 0
i(0).mkhi.mi.dwExtraInfo = IntPtr.Zero
SendInput(1, i(0), Marshal.SizeOf(i(0)))
これは pinvoke.com からのものです。
Public Declare Function SendInput Lib "user32" (ByVal nInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer
Public Structure INPUT
Enum InputType As Integer
INPUT_MOUSE = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2
End Enum
Dim dwType As InputType
Dim mkhi As MOUSEKEYBDHARDWAREINPUT
End Structure
Public Structure MOUSEINPUT
Enum MouseEventFlags As Integer
MOUSEEVENTF_MOVE = &H1
MOUSEEVENTF_LEFTDOWN = &H2
MOUSEEVENTF_LEFTUP = &H4
MOUSEEVENTF_RIGHTDOWN = &H8
MOUSEEVENTF_RIGHTUP = &H10
MOUSEEVENTF_MIDDLEDOWN = &H20
MOUSEEVENTF_MIDDLEUP = &H40
MOUSEEVENTF_XDOWN = &H80
MOUSEEVENTF_XUP = &H100
MOUSEEVENTF_WHEEL = &H800
MOUSEEVENTF_VIRTUALDESK = &H4000
MOUSEEVENTF_ABSOLUTE = &H8000
End Enum
Dim dx As Integer
Dim dy As Integer
Dim mouseData As Integer
Dim dwFlags As MouseEventFlags
Dim time As Integer
Dim dwExtraInfo As IntPtr
End Structure
Public Structure KEYBDINPUT
Public wVk As Short
Public wScan As Short
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
Public Structure HARDWAREINPUT
Public uMsg As Integer
Public wParamL As Short
Public wParamH As Short
End Structure
Const KEYEVENTF_EXTENDEDKEY As UInt32 = &H1
Const KEYEVENTF_KEYUP As UInt32 = &H2
Const KEYEVENTF_UNICODE As UInt32 = &H4
Const KEYEVENTF_SCANCODE As UInt32 = &H8
Const XBUTTON1 As UInt32 = &H1
Const XBUTTON2 As UInt32 = &H2
<StructLayout(LayoutKind.Explicit)> Public Structure MOUSEKEYBDHARDWAREINPUT
<FieldOffset(0)> Public mi As MOUSEINPUT
<FieldOffset(0)> Public ki As KEYBDINPUT
<FieldOffset(0)> Public hi As HARDWAREINPUT
End Structure
微妙。システムがアイドル状態ではないことをWindowsに通知する公式の方法は、SetThreadExecutionStateです。これにより、アイドルタイマーがリセットされます(または、合格した場合はオフになりますES_CONTINUOUS
)。ただし、SetThreadExecutionStateはアイドルタイマーをリセットしますが、スクリーンセーバーは停止しません。
具体的にはSPI_SETSCREENSAVEACTIVE
パラメータ。
これは機能しませんか?ここ見てないからビックリした。SetThreadExecutionState はスクリーン セーバーにはまったく影響せず、ディスプレイがスリープ状態になるだけであることに注意してください。
Mouse Jiglerを使用して、アイドル状態をリセットします。これは、不適切なときにスクリーンセーバーを起動する (そしてマシンをロックする) 傾向があるグループ ポリシーを回避します。たとえば、長いドキュメントを読んだり、複雑なコードのチャンクを調べたり、会話中に話したり、聞いたり、不定期に入力したりするときです。ミーティング。
マウスが毎秒 1px 斜めにジャンプするのは少し面倒なので、AutoHotKeyを使用して、基本的に同じことを行うスクリプトを作成するつもりですが、構成されたキーボード/マウスのアイドル タイムアウトの後にのみ、Shift キーを使用することもできます (または Scroll Lock) をマウスの移動の代わりに使用します。
MSDNから:
次の条件のいずれかが存在する場合、Windows はスクリーン セーバーを開始しません。
- アクティブなアプリケーションは、Windows ベースのアプリケーションではありません。
- CBT ウィンドウが存在します。
- アクティブなアプリケーションは、wParam パラメータが SC_SCREENSAVE 値に設定された WM_SYSCOMMAND メッセージを受け取りますが、そのメッセージを DefWindowProc 関数に渡しません。
ただし、注意事項があります。
Windows Vista 以降: ポリシーによってパスワード保護が有効になっている場合、アプリケーションが SC_SCREENSAVE 通知で何を行うかに関係なく、スクリーン セーバーが開始されます。
ES_CONTINUOUS で SetThreadExecutionState を使用しても、それは適用されるようです。
したがって、警告がなければ、次の選択肢があります。
- SetThreadExecutionState with ES_CONTINUOUS (他の回答で説明されているように)。
- コンピューター ベースのトレーニング ウィンドウを設置します (これにはフックが必要です)。
- SC_SCREENSAVE を指定した WM_SYSCOMMAND を DefWindowProc に渡さないでください。(アプリケーションがアクティブなアプリケーションである場合にのみ気にすると仮定します。)
- マウスの揺れをシミュレートするドングルを取り付けます。
最後のオプションは、パスワード保護ポリシーでも機能するという点で優れています。
このブログ投稿では、C++で何をする必要があるかについて詳しく説明しています。
Webサイトからの実際のコードスニペット:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_SCREENSAVE:
return 0;
case SC_MONITORPOWER:
return 0;
}
break;
}
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
誰も簡単で明白な解決策を指摘していないとは信じられません:
#include <windows.h>
void main()
{
while(1){
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = 1;
input.mi.dy = 1;
input.mi.mouseData = 0;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
input.mi.time = 0;
input.mi.dwExtraInfo = 0;
SendInput( 1, &input, sizeof(input) );
sleep(60000);
}
}
SystemParametersInfoを使用
して を取得しSCREENSAVETIMEOUT
、すぐにタイムアウトを同じ値に戻すことができます。スクリーンセーバーが起動しないようにしたい限り、タイマーで定期的にこれを行います。
これには、システム設定を実際に変更することなく、現在のカウントダウン タイマーをリセットする効果があります。
SetThreadExecutionState
他の回答が言及しているように、おそらく電力に影響を与えるために電話したいと思うでしょう。