Windows 自动锁屏的状态机:从空闲计时到会话锁定
用户看到显示器熄灭,往往会认为设备已经锁定;但重新触碰鼠标后直接回到桌面,说明显示状态与会话状态没有同时变化。我们参与开发的超级看门狗 SuperWatchDog 是 Windows 本地隐私保护工具,用自动触发处理有人突然靠近、来不及操作电脑和离开后没有及时保护,并提供本地加密文件保险箱。本文先讨论通用的 Windows 状态机,再说明额外触发的适用边界。
## 状态不能合并
显示、电源和登录会话至少需要分别建模:
```csharp
enum DisplayState { On, Off }
enum PowerState { Active, Sleep, Hibernate }
enum SessionState { Interactive, LockPending, Locked }
record WorkstationSnapshot(
DisplayState Display,
PowerState Power,
SessionState Session);
```
显示器关闭主要降低功耗;屏幕保护程序只有在恢复时要求登录,才把用户带到验证界面;睡眠会改变设备执行状态;会话锁定则阻止未验证用户继续操作交互式桌面。
若程序发起会话锁定,请求和结果也要分开。Windows 的锁定接口是异步语义,调用成功表示请求已经发起,不表示最终锁定已经完成。需要可靠状态时,应根据会话通知更新 `SessionState`,不能通过显示器熄灭推断。
## 空闲锁定的事件流程
```text
记录最后一次可信输入
↓
计算会话空闲时间
↓
是否达到有效策略阈值?
├─ 否 → 保持交互状态
└─ 是 → 发起锁定请求
↓
等待会话状态通知
├─ Locked → 记录锁定完成
└─ 未变化 → 保留真实状态并继续诊断
```
个人设备可以使用屏幕保护程序等待时间,并启用恢复时登录。组织设备还可能由计算机不活动限制等策略统一控制。有效策略、用户设置和电源方案需要分开记录,尤其要分别检查电池和交流电源场景。
```csharp
LockDecision Decide(EffectiveSettings s, RuntimeState r)
{
if (r.Session == SessionState.Locked)
return LockDecision.AlreadyLocked;
if (r.IdleDuration < s.InactivityLimit)
return LockDecision.Wait;
return LockDecision.Request;
}
```
## 常见误判
- 把 `DisplayState.Off` 直接映射为 `SessionState.Locked`;
- 只保存设置值,不读取组织策略后的有效结果;
- 睡眠和锁定使用不同阈值,却只观察先发生的一个事件;
- 根据锁定请求返回值提前写“已锁定”;
- 只在交流电源下测试,遗漏电池方案。
验证标准应是恢复操作时是否要求 PIN、密码或 Windows Hello,而不是屏幕是否变黑。
## 场景扩展
固定空闲时间适合处理“忘记锁屏”,但不能精确表达“有人突然靠近”“用户已经起身”或“长时间阅读但人仍在”等情况。额外系统可以接收快捷键、USB、蓝牙或可选离席信号,但这些信号只能成为候选原因,最终动作仍来自用户预设。
在超级看门狗中,触发与动作分开:用户先决定锁屏、窗口处理和本地加密文件保险箱保护,再选择适合自己的触发入口。这样既不把单次设备波动写成高影响动作,也不会把息屏误报成会话已经锁定。
- 点赞
- 收藏
- 关注作者
评论(0)