windows用getsystempowerstatus的aclinestatus字段判断ac状态,linux读/sys/class/power_supply/*/online文件,macos通过iokit查询kiopmisexternalpowerconnectedkey;三者语义不完全对齐,需注意无电池设备、虚拟机假值及状态变更实时性问题。

Windows 上用 GetSystemPowerStatus 判断 AC/Battery
Windows 提供了 GetSystemPowerStatus 这个 API,能直接读取当前电源连接状态、电池剩余电量等信息。它返回一个 SYSTEM_POWER_STATUS 结构体,其中 ACLineStatus 字段就是关键:AC_LINE_ONLINE 表示插着交流电,AC_LINE_OFFLINE 表示仅靠电池供电。
注意:这个函数不触发权限提升,也不需要管理员权限,但必须链接 kernel32.lib(VS 默认已链接)。
- 调用前建议先检查
GetSystemPowerStatus返回值是否为TRUE,失败时可能是系统不支持(比如某些嵌入式 Windows CE 变体)或结构体未初始化 -
ACLineStatus为AC_LINE_UNKNOWN是合法的,常见于无电池设备(如台式机)或驱动未上报电源状态时,不能直接当“AC 接通”处理 - 该函数是同步、轻量级的,适合每秒轮询,但没必要高频调用;一般在 UI 状态更新、节能策略切换点调用一次即可
Linux 下读取 /sys/class/power_supply/ 的 online 文件
Linux 没有统一 API,而是通过 sysfs 暴露电源信息。典型路径是 /sys/class/power_supply/AC/online 或 /sys/class/power_supply/BAT0/online,具体设备名因硬件而异,需先枚举目录。
读取 online 文件内容:值为 1 表示 AC 接通,0 表示断开;对电池设备,present 文件可判断电池是否存在,capacity 给出剩余百分比。
- 不要硬编码路径,应遍历
/sys/class/power_supply/下所有子目录,检查其online是否存在且可读 - 有些设备(如部分 Chromebook)把 AC 和电池状态合并在一个目录下,此时要同时看
online和status(值可能为Charging/Discharging) - 读文件可能失败(权限被禁、路径不存在、非标准内核配置),必须做
open()和read()错误检查,不能假设文件一定存在
macOS 需用 IOKit 获取 kIOPMIsExternalPowerConnectedKey
macOS 没有 sysfs,也不提供 Win32 风格 API,得走 IOKit 框架。核心是调用 IORegistryEntryCreateCFProperty 查询根域(IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOResources")))下的电源属性字典。
真正关心的键是 kIOPMIsExternalPowerConnectedKey,对应 CFBooleanRef 值:kCFBooleanTrue 表示外接电源已连接。
- 必须链接
IOKit.framework和CoreFoundation.framework,否则链接失败 - 该查询会触发 I/O 注册表快照,有一定开销,不适合高频调用;建议缓存结果并在收到
NSWorkspace.powerChangedNotification时刷新 - 沙盒应用默认无法访问 IOKit,需在 entitlements 中添加
com.apple.developer.kernel.iokit(仅限 macOS App Store 外分发场景,MAS 应用不可用)
跨平台封装要注意的兼容性断裂点
三个平台的电源状态语义并不完全对齐:Windows 的 AC_LINE_ONLINE 不代表电池正在充电(可能满电断充),Linux 的 online=1 也不排除电池被禁用,macOS 的 kIOPMIsExternalPowerConnectedKey 更接近“物理插头已接入”。所以抽象成 “is_on_ac()” 函数时,行为边界必须明确。
- 别把 “AC 在线” 等同于 “正在充电”——后者还需查电池
status或Charging字段 - 桌面平台(无电池)可能永远返回 “AC 在线”,但程序逻辑若依赖电池存在,需额外检查电池设备是否被枚举到
- 虚拟机里这些接口常返回假值(如 VMware 虚拟机中
/sys/class/power_supply/可能为空),应设置 fallback 行为(例如默认视为 AC 模式)
最易被忽略的是状态变更的实时性:所有平台都不保证事件立即通知,轮询间隔和事件监听需结合使用;单纯依赖一次读取,在笔记本拔插电源的瞬间可能错过过渡态。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











