Python空闲时间检测脚本在系统连续运行超一月时输出异常
问题分析与解决
问题根源
- 32位计时函数溢出:原代码使用的
GetTickCount()是32位无符号整数,最大值对应约49.7天,系统连续运行超过这个时间后会溢出归零,导致计算出的空闲时长异常偏小。 - 错误的取模截断:原代码中
(millis / (1000.0*60.0))%60的取模操作,会把超过60分钟的空闲时长直接截断为分钟部分,比如实际空闲1小时10分钟会被计算成10分钟,这就是你看到“实际空闲数小时却显示不足10分钟”的直接原因。
修正后的脚本
from ctypes import Structure, windll, c_uint, sizeof, byref, c_ulonglong class LASTINPUTINFO(Structure): _fields_ = [ ('cbSize', c_uint), ('dwTime', c_uint), ] def get_idle_duration_seconds(): lastInputInfo = LASTINPUTINFO() lastInputInfo.cbSize = sizeof(lastInputInfo) windll.user32.GetLastInputInfo(byref(lastInputInfo)) # 使用64位计时函数避免长期运行溢出 current_tick = windll.kernel32.GetTickCount64() # 将32位的最后输入时间转为64位,避免运算溢出 millis = current_tick - c_ulonglong(lastInputInfo.dwTime).value return round(millis / 1000.0) # 返回秒级空闲时长 # 测试执行 if __name__ == "__main__": idle_sec = get_idle_duration_seconds() print(f"当前空闲时长:{idle_sec} 秒")
关键修改说明
- 替换
GetTickCount()为GetTickCount64():这是64位计时函数,系统运行数百年才会溢出,彻底解决长期运行后的计时异常问题。 - 类型转换避免运算溢出:把
lastInputInfo.dwTime(32位值)转为64位整数后再计算,防止32位与64位值运算时的溢出错误。 - 直接返回秒级时长:移除了错误的取模操作,确保空闲时长超过1小时也能正确计算。
内容的提问来源于stack exchange,提问作者Nambirajan M
相关产品推荐
相关产品推荐

