如何创建Windows进入睡眠模式前触发的Python事件
嘿,我发现你现在的代码是主动调用系统睡眠,但你真正想要的是当Windows收到睡眠请求时自动记录时间对吧?咱们来调整一下思路,因为原代码的逻辑和你的需求不太匹配——你现在是主动触发睡眠,而不是监听系统本身的睡眠事件(比如用户点开始菜单的睡眠、电源超时触发的睡眠)。
解决方案思路
要实现监听Windows的睡眠请求,我们需要和系统的电源事件API交互,这里有两种常用的方法,都能满足你的需求:
方法1:使用pywin32监听系统电源广播消息
这种方法通过创建一个隐藏窗口来接收系统的电源通知,能精准捕获睡眠、唤醒等事件。
- 首先安装依赖库:
pip install pywin32
- 编写监听脚本(比如命名为
SleepMonitor.py):
import win32gui import win32api import win32con import datetime class PowerMonitorWindow: def __init__(self): # 注册自定义窗口类,用于接收系统消息 wc = win32gui.WNDCLASS() wc.lpfnWndProc = self.wnd_proc wc.lpszClassName = "PowerMonitorWindowClass" wc.hInstance = win32api.GetModuleHandle(None) class_atom = win32gui.RegisterClass(wc) # 创建隐藏窗口 self.hwnd = win32gui.CreateWindow( class_atom, "PowerMonitor", 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None ) # 注册电源事件通知 win32gui.RegisterPowerSettingNotification( self.hwnd, win32con.GUID_SYSTEM_POWER_SETTING, win32con.DEVICE_NOTIFY_WINDOW_HANDLE ) def wnd_proc(self, hwnd, msg, wparam, lparam): # 处理电源广播消息 if msg == win32con.WM_POWERBROADCAST: if wparam == win32con.PBT_APMSUSPEND: # 捕获系统即将进入睡眠的事件 sleep_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") with open("sleep_log.txt", "a", encoding="utf-8") as f: f.write(f"系统进入睡眠: {sleep_time}\n") print(f"已记录睡眠时间: {sleep_time}") elif wparam in [win32con.PBT_APMRESUMEAUTOMATIC, win32con.PBT_APMRESUMESUSPEND]: # 捕获系统唤醒事件(自动唤醒/用户手动唤醒) wake_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") action = "系统自动唤醒" if wparam == win32con.PBT_APMRESUMEAUTOMATIC else "用户手动唤醒" with open("sleep_log.txt", "a", encoding="utf-8") as f: f.write(f"{action}: {wake_time}\n") print(f"已记录唤醒时间: {wake_time}") return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) def run(self): # 启动消息循环,保持脚本运行 print("系统睡眠监视器已启动,等待电源事件...") win32gui.PumpMessages() if __name__ == "__main__": monitor = PowerMonitorWindow() monitor.run()
- 运行脚本:
执行这个脚本后,它会在后台运行,只要系统收到睡眠请求,就会自动把时间写入当前目录的sleep_log.txt文件中。
方法2:使用wmi监听电源事件
这种方法更简洁,通过WMI(Windows Management Instrumentation)来监听系统电源事件。
- 安装依赖库:
pip install wmi
- 编写监听脚本:
import wmi import datetime def log_power_event(action): """记录电源事件到文件""" event_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") with open("sleep_log.txt", "a", encoding="utf-8") as f: f.write(f"{action}: {event_time}\n") print(f"{action}: {event_time}") # 初始化WMI连接 c = wmi.WMI() # 监听Win32_PowerManagementEvent事件 print("系统电源事件监视器已启动...") for event in c.Win32_PowerManagementEvent.watch_for(): if event.EventType == 4: # EventType=4 表示系统即将进入睡眠 log_power_event("系统进入睡眠") elif event.EventType == 7: # EventType=7 表示系统从睡眠中唤醒 log_power_event("系统唤醒")
运行这个脚本后,同样会在后台监听,捕获睡眠和唤醒事件并记录时间。
为什么原代码不适用?
你原来的主代码是调用Sleep.py主动触发系统睡眠,这是主动执行睡眠操作,而不是监听系统的睡眠请求。只有当你运行这个脚本时才会触发睡眠并记录时间,但无法捕获用户手动触发、电源计划触发的睡眠事件。
内容的提问来源于stack exchange,提问作者Subbu
相关产品推荐
相关产品推荐

