Windowsスクリーンセーバーが起動しないようにするための推奨される方法はありますか?私が見つけた最も近いものは この記事 ですが、私が本当にやりたいのは、現在設定されているスクリーンセーバーの値にだまされるのではなく、コンピューターがアイドル状態ではないことをWindowsに伝えることです。
テストのために、スクリーンセーバーを1分に設定し、パスワードが必要でした。
SC_SCREENSAVEをキャプチャし、VB.Net。Netで-1を返してみました。コメントされているように、スクリーンセーバーのパスワードがない場合は機能しますが、スクリーンセーバーの場合は失敗しますパスワードはアクティブです(Windows XPで試しました)。また、これをタイマーのティックイベントに1000ミリ秒ごとに入れます。
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秒ごとにトリガーされるタイマー内で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
具体的には、SPI_SETSCREENSAVEACTIVE
パラメータ。
これは機能しませんか?ここに見えなかったのでびっくりしました。 SetThreadExecutionStateはスクリーンセーバーにはまったく影響せず、ディスプレイのスリープだけに影響することに注意してください。
微妙。システムがアイドル状態ではないことをWindowsに通知する公式の方法は、SetThreadExecutionStateです。これにより、アイドルタイマーがリセットされます(または、ES_CONTINUOUS
を渡すとオフになります)。ただし、SetThreadExecutionStateがアイドルタイマーをリセットしても、スクリーンセーバーは停止しません!
Mouse Jiggler を使用してアイドル状態をリセットします。これは、スクリーンセーバーを開始する(そしてマシンをロックする)傾向のあるグループポリシーを回避します。長いドキュメントを読んでいるとき、複雑なコードのチャンクを勉強しているとき、または話しているとき/聞いているとき/常に入力していないときなどです。会議。
マウスが毎秒1px斜めにジャンプするのは少し面倒なので、 AutoHotKey を使用して、基本的に同じことを行うスクリプトを作成するつもりですが、設定されたキーボード/マウスのアイドルタイムアウトの後のみです。マウスを動かす代わりにShiftキー(またはScroll Lock)を使用することもできます。
誰も簡単で明白な解決策を指摘していないとは信じられません:
#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);
}
}
から [〜#〜] msdn [〜#〜] :
次のいずれかの条件が存在する場合、Windowsはスクリーンセーバーを起動しません。
- アクティブなアプリケーションはWindowsベースのアプリケーションではありません。
- CBTウィンドウが存在します。
- アクティブなアプリケーションは、wParamパラメーターがSC_SCREENSAVE値に設定されたWM_SYSCOMMANDメッセージを受信しますが、メッセージをDefWindowProc関数に渡しません。
ただし、注意点があります。
Windows Vista以降:ポリシーによってパスワード保護が有効になっている場合、アプリケーションがSC_SCREENSAVE通知をどのように処理するかに関係なく、スクリーンセーバーが開始されます。
これは、ES_CONTINUOUSでSetThreadExecutionStateを使用する場合でも当てはまるようです。
したがって、警告がなかった場合、選択は次のようになります。
最後のオプションは、パスワード保護ポリシーでも機能するという点でニースです。
このブログ投稿 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);
}
Windows 7以降では、Power ManagementAPIのPowerSetRequest()
をPowerRequestDisplayRequired
とともに使用します
https://msdn.Microsoft.com/en-us/library/windows/desktop/dd405534(v = vs.85).aspx
以前のバージョンのWindowsでは、Eddie Parkerの回答で詳しく説明されているように、WM_SYSCOMMAND-SC_SCREENSAVEメッセージをインターセプトします。
SystemParametersInfo を使用してSCREENSAVETIMEOUT
を取得し、すぐにタイムアウトを同じ値に戻すことができます。スクリーンセーバーが実行されないようにする限り、タイマーで定期的にこれを実行します。
これには、実際にシステム設定を変更せずに、現在のカウントダウンタイマーをリセットする効果があります。
他の回答が述べているように、パワーに影響を与えるためにSetThreadExecutionState
を呼び出すこともできます。
タイムアウトカウンターをリセットするだけです
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE、1、nil、SPIF_SENDWININICHANGE);
AutoHotkeyは、スクリプトで1ライナーのDllCallを使用してSystemParametersInfo(SPI_SETSCREENSAVEACTIVE)を設定し、.ahkスクリプトを使用してこれを簡単に実行できます。
スクリーンセーバーを無効にするAutoHotkeyコード:
DllCall("SystemParametersInfo", Int, 17, Int, 0, UInt, NULL, Int, 2)
スクリーンセーバーを有効にするAutoHotkeyコード:
DllCall("SystemParametersInfo", Int, 17, Int, 1, UInt, NULL, Int, 2)
参照フォーラムスレッド:
F13Key -- スクリーンセーバーとSystemParametersInfoの切り替え
SKAN -- スクリーンセーバーを一時的に無効にする方法
From JD Design Freeware -- Flipss.exe(download 12kb) は、SPI_SETSCREENSAVEACTIVEを設定するコマンドラインユーティリティです。
"FlipSS.exe -h" to see the current state.
"FlipSS.exe /on" to set the screensaver on.
"FlipSS.exe /off" to set the screensaver off.