You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中调用Win32 API的PowerRegisterForEffectivePowerModeNotifications?

实现Windows有效电源模式变更的Python回调

因为pywin32未封装PowerRegisterForEffectivePowerModeNotifications API,我们可以直接用ctypes调用Windows原生的powrprof.dll来实现需求。以下是完整的实现方案:

核心思路

Windows的PowerRegisterForEffectivePowerModeNotifications函数用于注册电源模式变更通知,我们需要通过ctypes声明该函数、对应枚举类型和回调函数原型,注册回调后启动消息循环接收通知。

完整代码示例

import ctypes
from ctypes import wintypes

# 加载电源相关的系统库
powrprof = ctypes.WinDLL('powrprof.dll')
user32 = ctypes.WinDLL('user32.dll')

# 定义电源模式枚举(对应Windows API中的POWER_MODE)
class POWER_MODE(ctypes.c_uint):
    PowerModeBalanced = 0x00000000
    PowerModePerformance = 0x00000001
    PowerModeBatterySaver = 0x00000002
    PowerModeGame = 0x00000004  # 游戏模式

# 定义通知类型枚举(对应Windows API中的POWER_MODE_NOTIFICATION_TYPE)
class POWER_MODE_NOTIFICATION_TYPE(ctypes.c_uint):
    PowerModeNotificationEffectivePowerMode = 0x00000000

# 定义回调函数的原型
PowerModeCallback = ctypes.WINFUNCTYPE(
    wintypes.BOOL,
    wintypes.LPCVOID,  # 上下文参数
    wintypes.DWORD,    # 通知类型
    wintypes.LPCVOID   # 通知数据(指向POWER_MODE结构)
)

# 声明注册通知的API函数
powrprof.PowerRegisterForEffectivePowerModeNotifications.argtypes = [
    POWER_MODE_NOTIFICATION_TYPE,
    PowerModeCallback,
    wintypes.LPCVOID,
    wintypes.PHANDLE
]
powrprof.PowerRegisterForEffectivePowerModeNotifications.restype = wintypes.DWORD

# 声明注销通知的API函数
powrprof.PowerUnregisterPowerSettingNotification.argtypes = [wintypes.HANDLE]
powrprof.PowerUnregisterPowerSettingNotification.restype = wintypes.DWORD

# 自定义回调逻辑:电源模式变更时触发
def on_power_mode_change(context, notification_type, notification_data):
    current_mode = ctypes.cast(notification_data, ctypes.POINTER(POWER_MODE)).contents.value
    mode_map = {
        POWER_MODE.PowerModeBalanced: "平衡模式",
        POWER_MODE.PowerModePerformance: "高性能模式",
        POWER_MODE.PowerModeBatterySaver: "节电模式",
        POWER_MODE.PowerModeGame: "游戏模式"
    }
    print(f"检测到电源模式变更:{mode_map.get(current_mode, f'未知模式(0x{current_mode:08X})')}")
    return True

# 注册通知回调
callback = PowerModeCallback(on_power_mode_change)
notification_handle = wintypes.HANDLE()
register_result = powrprof.PowerRegisterForEffectivePowerModeNotifications(
    POWER_MODE_NOTIFICATION_TYPE.PowerModeNotificationEffectivePowerMode,
    callback,
    None,
    ctypes.byref(notification_handle)
)

if register_result != 0:
    raise RuntimeError(f"注册通知失败,错误码: {register_result}")

print("已注册电源模式变更监听,按Ctrl+C退出...")

# 启动消息循环处理系统通知
try:
    msg = wintypes.MSG()
    while user32.GetMessageW(ctypes.byref(msg), None, 0, 0) != 0:
        user32.TranslateMessage(ctypes.byref(msg))
        user32.DispatchMessageW(ctypes.byref(msg))
except KeyboardInterrupt:
    print("\n正在清理资源...")
    powrprof.PowerUnregisterPowerSettingNotification(notification_handle)
    print("监听已注销")

代码说明

  • 系统库调用:通过ctypes直接加载powrprof.dll和user32.dll,调用未被pywin32封装的原生API。
  • 枚举类型匹配:严格对应Windows API中的枚举定义,保证参数类型兼容。
  • 回调逻辑:on_power_mode_change会在电源模式(包括游戏模式)切换时触发,解析并输出当前模式。
  • 消息循环:Windows的系统通知需要通过消息泵分发,必须启动GetMessage循环才能接收事件。
  • 资源清理:退出时主动注销通知,避免系统资源泄漏。

验证方式

在Windows设置中切换电源模式(比如开启/关闭游戏模式),控制台会实时输出模式变更信息。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:32:30