使用GetLastInputInfo获取系统空闲时间时计数器异常重置的原因排查
问题:GetLastInputInfo()空闲计数器5分钟后自动重置
我需要在应用程序触发事件时获取系统空闲时间,使用GetLastInputInfo()函数后发现:无鼠标或键盘操作的情况下,空闲计数器会在5分多钟后自动重置为0。我已经关闭屏保,且禁用了系统和显示器的待机、睡眠设置。
测试代码:
procedure TMsgForm.Timer1Timer(Sender: TObject); var mins, secs, T0, T1, TD: Cardinal; LastInput: TLastInputInfo; begin LastInput.cbSize:=SizeOf(TLastInputInfo); if not GetLastInputInfo(LastInput) then Caption := 'error' else begin T0 := GetTickCount; T1 := LastInput.dwTime; TD := T0 - T1; secs := TD div 1000; mins := secs div 60; Caption := 'T0='+IntToStr(T0)+' T1='+IntToStr(T1)+' TD='+IntToStr(TD)+' secs='+IntToStr(secs)+' mins='+IntToStr(mins); end; end;
更新1:关闭所有程序后等待5分钟,问题仍存在。排除第三方程序模拟用户输入的可能,推测是系统层面因素导致;另一台电脑测试无此问题,计数器不会重置。
更新2:挂钩键盘和鼠标后,计数器重置时刻未收到任何输入事件,推断计数器由其他系统来源触发重置。
排查方向与解决办法
- 检查系统服务或后台进程:
部分系统服务(如电源管理类、硬件驱动服务)可能触发计数器重置。通过任务管理器「详细信息」面板观察5分钟左右的进程活动,或用Process Monitor监控是否有进程调用SetLastInputInfo等修改输入状态的API。 - 排查硬件驱动:
触控板、无线键鼠、网卡或显卡的驱动可能在后台发送模拟输入信号维持设备状态。尝试更新或卸载近期改动过的可疑驱动,测试问题是否消失。 - 检查电源设置深层选项:
即使禁用了待机睡眠,电源计划的隐藏选项(如「USB选择性暂停」「PCI Express电源管理」)可能导致硬件唤醒,间接重置计数器。进入「电源选项 > 更改计划设置 > 更改高级电源设置」,将这类选项全部设为「禁用」后测试。 - 自定义空闲计时替代方案:
若系统层面排查无果,可放弃依赖GetLastInputInfo,自行维护空闲时长:- 挂钩全局鼠标、键盘消息(如
WM_MOUSEMOVE、WM_KEYDOWN); - 用全局变量记录最后输入的时间戳;
- 通过当前时间与时间戳的差值计算空闲时长,这种方式不受系统其他因素干扰。
- 挂钩全局鼠标、键盘消息(如
内容的提问来源于stack exchange,提问作者Marus Gradinaru
相关产品推荐
相关产品推荐

