Windows 提供了两种方式唤醒熄屏的显示器:发送系统消息或模拟鼠标输入。
PowerShell 一行命令
powershell -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)"
0x0112 是 WM_SYSCOMMAND,0xF170 是 SC_MONITORPOWER,最后参数 -1 表示打开显示器(2 关闭,1 低功耗)。
C++ SendMessage
#include <windows.h>
int main() {
SendMessage(HWND_BROADCAST,
WM_SYSCOMMAND,
SC_MONITORPOWER,
-1);
return 0;
}
SC_MONITORPOWER 的第四个参数含义:
-1= 打开显示器1= 低功耗2= 关闭显示器
更可靠:模拟鼠标移动(推荐)
部分机器上 SC_MONITORPOWER 不一定生效,模拟极小鼠标移动更稳定:
#include <windows.h>
int main() {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dx = 1;
input.mi.dy = 1;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
SendInput(1, &input, sizeof(INPUT));
return 0;
}
等效于”假装用户动了一下鼠标”,几乎在所有机器上都能触发屏幕唤醒。
PowerShell 版本
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAPI {
[DllImport("user32.dll")]
public static extern void mouse_event(
int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
}
"@
[WinAPI]::mouse_event(1, 0, 1, 0, 0)
Session 0 限制
如果代码在 Windows 服务里运行,以上方法大概率无效,因为服务运行在 Session 0,无法操作用户桌面。常见解决方案:
- 改用计划任务(交互式模式运行)
- 注入用户 Session 进程
- 使用
WTSSendMessage跨 Session 通信
这是服务程序操控 GUI 时的常见踩坑点。
