2026年1月19日晚上,我帮朋友跑一个视频转码,顺手开了几路下载任务,然后合上笔记本就去睡了。第二天起来,转码进度停在 37%,下载任务全部报错,原因都是同一个——凌晨某个时刻,系统认为我已经离开,触发了“空闲超时关机”策略。系统设置里写得很清楚:电脑100分钟无操作后关机。那台机器上还挂着十几个后台任务,我就是被这个“100分钟无操作自动关机”坑掉的。
很多人遇到这种情况的第一反应是去改电源计划,把睡眠和关机都设成“从不”。但有些电脑是公司策略锁死的,有些是任务计划里加了定时关机,还有的场景根本不允许你改设置。于是就有了另一个思路:模拟鼠标操作,让系统始终认为“有人还在用电脑”。这篇文章就从这个需求说起,适合需要长期挂机跑任务的个人用户,也适合需要在演示、监控、自动化测试时保持会话不掉的开发者。我会把原理、方案选型、可复制的脚本和踩坑记录都放出来,尽量一次说透。
1. 为什么电脑会“以为你离开”了——系统空闲判定与关机/锁屏的底层逻辑
1.1 系统不是按照“人”,而是按照“输入事件”判断
无论是 Windows、macOS 还是 Linux 桌面,判断用户是否在场的方式都不是摄像头,而是输入事件。鼠标移动、滚轮滚动、键盘按键、触摸板点击,都会被系统记录成一条带时间戳的“最近输入事件”。Windows 上对应的 API 是 GetLastInputInfo,它返回系统最后一次输入发生的时间,系统拿这个时间和当前时间一减,就得出了“空闲时间”。
屏幕保护、锁屏、电源管理、甚至某些软件的“自动离线”定时器,全都基于这个空闲时间做判断。所以你坐在电脑前看视频不动鼠标,系统依然会认为你离开了——因为在它眼里,长时间没有输入事件就等于人不在。这个设计本身是为了省电和安全,但对挂机跑任务的人来说,就成了噩梦。
模拟鼠标操作的本质,就是伪造这条“最近输入事件”。只要定期给系统注入一次真实的鼠标移动事件,空闲时间就会被清零,屏幕保护、睡眠、锁屏那些基于空闲计时的策略就始终不会触发。注意关键词是“真实”。单纯调用 SetCursorPos 把光标挪个位置,在很多版本的 Windows 上并不会生成输入事件,也不会刷新空闲计时器,必须用 mouse_event 或 SendInput 这类能注入系统输入队列的 API。这个细节是很多号称“鼠标精灵”却无效的根本原因。
1.2 三种把你“踢下线”的机制:屏幕关闭、睡眠休眠、定时关机
实际动手以前,先要搞清楚系统到底是通过哪种机制把你踢下线的。我遇到过的情况大概可以分成三类:
| 机制 | 现象 | 对任务的影响 | 模拟鼠标是否有效 |
|---|---|---|---|
| 屏幕关闭 | 显示器黑屏,主机还在运行 | 基本没影响,只是看不见画面 | 有效,但没必要 |
| 睡眠/休眠 | 整机进入低功耗,风扇停转,网络断开 | 任务中断,等待状态丢失 | 有效,是最常见的用途 |
| 定时关机 | 系统在空闲 N 分钟后执行关机或重启 | 任务中断,进程全部结束 | 不一定有效,要看触发方式 |
屏幕关闭是最温和的,它只是把显示输出关掉,后台任务照常跑。这种场景不需要任何模拟输入,去电源设置里把“关闭显示器”改成“从不”或者延长就行。睡眠和休眠就比较麻烦,一旦进入,CPU 暂停、内存进入自刷新,视频渲染、下载任务、脚本进程全部停摆。模拟鼠标在这里是真正管用的。
定时关机要单独说。它可能是电源计划里的“休眠超时”,也可能是任务计划程序里添加的“系统空闲 N 分钟后运行 shutdown.exe”。如果是前者,模拟鼠标能防住;如果是后者,就要看任务是怎么写的——有些计划任务会忽略输入事件,只认“系统空闲时间”这个计数器,你就算每 50 分钟动一下鼠标,某些版本的 Windows 依旧会在累计空闲满 100 分钟后执行关机。这种情况需要的是找到并调整那个计划任务,而不是靠模拟
