
Windows10 시스템에서 로컬로 디스플레이를 끄는 솔루션이 많이 있습니다. 그것들은 모두 다음 SendMessage 줄의 일부 형태입니다. 이를 수행하는 nircmd와 같은 작은 실행 파일도 있습니다. 그러나 OpenSSH를 통해 이들 중 하나를 실행할 때 약간의 제한이 있는 것 같습니다. 내 OpenSSH는 내 로컬 사용자와 정확히 동일한 자격 증명을 사용하도록 구성되어 있으므로 실제로 아무 일도 일어나지 않는 이유를 알 수 없습니다. ps 스크립트 버전은 간단한 1을 반환하고 nircmd와 같은 솔루션은 전혀 아무것도 반환하지 않습니다. 오류도 아닙니다. 여기서 무슨 일이 일어날 수 있고 어떻게 작동하게 만들 수 있는지에 대한 통찰력이 있습니까?
샘플 스크립트:
powershell (추가 유형 '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -이름 a -Pas)::SendMessage(- 1,0x0112,0xF170,2)
편집: 아마도 다른 것을 추가해야 할 것 같아요nircmd오디오 음소거와 같은 옵션은 문제 없이 작동합니다.
답변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