GetSystemPowerStatus 是 Windows 获取电池电量最轻量可靠的方式,返回 SYSPOWERSTATUS 结构体,BatteryLifePercent 为 0–100 或 255(未知),需检查返回值并初始化结构体,不依赖管理员权限且兼容 XP SP3+。

Windows平台用 GetSystemPowerStatus 获取电池状态
Windows 提供了现成的 API,GetSystemPowerStatus 是最轻量、最可靠的方式,不需要管理员权限,也不依赖 WMI 或 PowerShell。它返回一个 SYSPOWERSTATUS 结构体,其中 BatteryLifePercent 字段就是你想要的剩余电量(0–100),ACLineStatus 可判断是否插电。
常见错误是忽略返回值检查或没初始化结构体:该函数失败时返回 0,但很多代码直接读 BatteryLifePercent,而未插电池的设备(比如台式机)或虚拟机可能返回 255 或无效值。
- 调用前必须将
dwFlags成员设为 0,否则部分 Windows 版本会读取失败 -
BatteryLifePercent为 255 表示“未知”,不是 100%;需显式判断:if (status.BatteryLifePercent != 255) - 该函数不触发 UAC,但仅适用于 Windows(XP SP3+),不跨平台
#include <windows.h>
#include <iostream>
int main() {
SYSTEM_POWER_STATUS status = {};
if (GetSystemPowerStatus(&status)) {
if (status.BatteryLifePercent != 255) {
std::cout << "Battery: " << (int)status.BatteryLifePercent << "%\n";
} else {
std::cout << "Battery status unknown\n";
}
}
}
Linux 下读取 /sys/class/power_supply/ 文件系统
Linux 没有统一 API,但几乎所有现代发行版都通过 sysfs 暴露电池信息,路径通常是 /sys/class/power_supply/BAT0/(也可能叫 BAT1、axp288_fuel_gauge 等)。关键文件是 capacity(当前电量百分比)和 status(Charging/Discharging/Full)。
容易踩的坑是硬编码路径或忽略权限问题:普通用户默认可读这些文件,但某些 OEM 设备(如部分 ThinkPad 或 Chromebook)可能把电池放在非标准路径,或需要 udev 规则支持。
立即学习“C++免费学习笔记(深入)”;
- 先遍历
/sys/class/power_supply/下所有子目录,检查是否存在capacity文件 -
capacity内容是纯数字字符串(如"73\n"),需std::stoi转换,注意捕获std::invalid_argument - 若读到
energy_now和energy_full,可用它们算出更精确百分比(尤其对老电池),但多数设备只提供capacity
macOS 上用 IOKit 获取 AppleSmartBattery 数据
macOS 没有 sysfs,必须用 IOKit 框架。核心是获取 IOServiceMatching("AppleSmartBattery") 对应的服务,再用 IORegistryEntryCreateCFProperties 读取属性字典。关键键是 CurrentCapacity 和 MaxCapacity,两者相除即为剩余电量。
新手常卡在链接阶段:必须显式链接 -framework IOKit -framework CoreFoundation,且 Xcode 默认不启用 C++17 的 <filesystem></filesystem>,别试图用它找设备路径——IOKit 不走文件系统。
- IORegistry 查询可能返回多个匹配项(如带触控板电池),需过滤
DesignCapacity或LegacyBatteryInfo存在的条目 -
CurrentCapacity和MaxCapacity是 CFNumberRef,要用CFNumberGetValue转成 int64_t,不能直接强转 - 沙盒应用(如 App Store 分发)默认无权访问 IOKit,需在 entitlements 中添加
com.apple.developer.kernel.extended-system-info
跨平台封装要注意的三个实际限制
没有“一次编写,到处获取电量”的标准方案。即使封装成统一接口,底层行为差异仍会导致逻辑分歧:
- Windows 的
BatteryLifePercent是整数,Linuxcapacity也是整数,但 macOS 返回的是浮点精度的原始容量值,四舍五入策略要自己定 - Linux 和 macOS 都可能有多个电池(双电池笔记本、TSMC 电池模组),而 Windows API 只返回主电池汇总值
- 休眠唤醒后,Linux 的 sysfs 值可能延迟更新几秒,macOS 的 IOKit 属性偶尔缓存旧值,建议加 1–2 秒重试逻辑而非单次读取
真正麻烦的不是读取本身,而是处理“无电池”“电量突变”“驱动未加载”这三类边界态——它们不会报错,只会静默返回无效数据。


















