通过 OpenSSH 关闭 Win10 显示器

通过 OpenSSH 关闭 Win10 显示器

有很多解决方案可以在 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)

来源

编辑:也许我应该添加其他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

相关内容