如何让Python统计Windows睡眠时长 解决定时关弹窗休眠后失效问题
方案1:改用绝对时间戳计时(最推荐,无额外依赖)
你遇到的核心问题是time.sleep()是相对计时,系统睡眠时计时会暂停,改用绝对时间戳判断就能完全避开这个问题,同时保留4小时定时的逻辑,不会额外消耗性能。
修改后的代码如下:
import time import pygetwindow as gw # 初始化下次检查时间为0,程序启动后立即执行第一次检查 next_check_timestamp = 0 def is_window_open(): # 替换为你原来的窗口检测逻辑 return len(gw.getWindowsWithTitle("你要关闭的窗口标题")) > 0 def close_window(): # 替换为你原来的关窗逻辑 target_windows = gw.getWindowsWithTitle("你要关闭的窗口标题") if target_windows: target_windows[0].close() while True: current_timestamp = time.time() # 到达设定的检查时间或已超时就执行检测 if current_timestamp >= next_check_timestamp: if is_window_open(): close_window() # 设置4小时后(可提前60秒避免误差)再次检查 next_check_timestamp = current_timestamp + 4 * 3600 - 60 # 每次循环休眠1秒,CPU占用几乎为0 time.sleep(1)
这个逻辑下,系统唤醒后会直接读取当前真实时间,只要当前时间已经超过预设的检查时间,就会立刻执行窗口检测和关闭操作,完全不受系统睡眠的影响。
方案2:监听Windows电源事件(需要额外依赖)
你之前监听不到电源事件是因为后台运行的控制台脚本没有窗口句柄和消息循环,系统的WM_POWERBROADCAST消息无法投递到你的进程,可通过pywin32创建隐藏消息窗口解决:
- 先安装依赖:
pip install pywin32 - 参考代码:
import time import win32gui import win32con import pygetwindow as gw # 全局标记:是否刚从睡眠中唤醒 just_woke_up = False next_check_timestamp = 0 # 窗口消息处理函数 def power_event_proc(hwnd, msg, wparam, lparam): global just_woke_up if msg == win32con.WM_POWERBROADCAST: # 捕获系统唤醒事件 if wparam in (win32con.PBT_APMRESUMEAUTOMATIC, win32con.PBT_APMRESUMESUSPEND): just_woke_up = True return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) # 注册隐藏窗口类,用于接收系统消息 wc = win32gui.WNDCLASS() wc.lpfnWndProc = power_event_proc wc.lpszClassName = "PowerEventMonitorWindow" win32gui.RegisterClass(wc) # 创建隐藏窗口,不需要显示 win32gui.CreateWindow(wc.lpszClassName, "Power Monitor", 0, 0, 0, 0, 0, 0, 0, 0, None) # 原有窗口处理逻辑 def is_window_open(): return len(gw.getWindowsWithTitle("你要关闭的窗口标题")) > 0 def close_window(): target_windows = gw.getWindowsWithTitle("你要关闭的窗口标题") if target_windows: target_windows[0].close() while True: # 处理消息队列中的系统事件 win32gui.PumpWaitingMessages() current_timestamp = time.time() # 刚唤醒或到检查时间就执行检测 if just_woke_up or current_timestamp >= next_check_timestamp: just_woke_up = False if is_window_open(): close_window() next_check_timestamp = current_timestamp + 4 * 3600 - 60 time.sleep(1)
这个方案可以在系统唤醒的第一时间触发窗口检测,响应速度比方案1快1秒以内,差异很小。
两个方案都兼容你现有开机自启、后台运行、多线程的架构,不需要修改你其他线程的逻辑。
内容的提问来源于stack exchange,提问作者mtm
相关产品推荐
相关产品推荐

