
Windows10 マシンでローカルにディスプレイをオフにする方法はたくさんあります。それらはすべて、次の SendMessage 行の形式です。また、これを行う nircmd などの小さな実行可能ファイルもあります。ただし、OpenSSH 経由でそれらを実行すると、何らかの制限があるようです。私の OpenSSH は、ローカル ユーザーとまったく同じ資格情報を使用するように構成されているため、何も起こらない理由がわかりません。ps スクリプト バージョンは単純な 1 を返し、nircmd などのソリューションは何も返しません。エラーさえ返しません。ここで何が起こるのか、またそれを機能させる方法について何か知見はありますか?
サンプルスクリプト:
powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2)
編集: 他にも追加した方がいいかもしれないニルコオーディオをミュートするなどのオプションは問題なく動作します。
答え1
これは、対話型 Windows セッションが現在のセッションではないため、物理ディスプレイがアクティブに接続されているコンテキストで実行されていないためです。サウンドやその他の機能はアクティブですが、ディスプレイはセッションに関連付けられています。対話型でログインするか、psexec などを使用して、ユーザーのコンテキストで PowerShell プロセスを実行することができます。psexec を使用しても問題ない場合は、次のものを使用できます。
FOR /F "usebackq tokens=4" %s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO psexec -accepteula -nobanner -d -i %s -w "%windir%" powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2)
ただし、これには psexec が必要になります。
対話型セッションが複数ある場合は、複数回実行されます。
バッチから実行する場合は、両方の %s を %%s に置き換える必要があります。
これは対話型セッションを収集する部分です。
FOR /F "usebackq tokens=4" %s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO echo %s
以下をバッチ ファイルにコピーし、ターミナル エミュレータから実行できます。
FOR /F "usebackq tokens=4" %%s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO (
psexec -accepteula -nobanner -d -i %%s -w "%windir%" powershell -NoProfile -NoLogo -Command "(Add-Type '[DllImport(\"user32.dll\")]public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2)"
)
唯一の違いは、それぞれ%s
が に変更されることです%%s
。
ディスプレイを無効にしようとしているコンピューターで対話的に実行すると失敗する可能性が高いことに注意してください。これは、対話型セッションがまだアクティブであるためです。
画面を起動するには、次の方法を使用できます (いくつかのデバイスでテスト済みで動作します)。
:: gather session handle
FOR /F "usebackq tokens=4" %%s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO SET hsession=%%s
:: wake display
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "(Add-Type '[DllImport(\"user32.dll\")]public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,-1)"
CALL :wait 2
:: reactivate session
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "$x=Add-Type '[DllImport(\"kernel32.dll\")]public static extern void SetThreadExecutionState(uint esFlags);' -name System -namespace Win32 -passThru;$x::SetThreadExecutionState([uint32]\"0x03\");Sleep 5;$x::SetThreadExecutionState([uint32]\"0x40\");"
CALL :wait 2
GOTO:EOF
:wait
SET dowait=%~1
IF "%dowait%"=="" SET dowait=10
ping -n %dowait% 127.0.0.1 >NUL
GOTO:EOF