Windows内核32.BatteryLifePercent=255

Windows内核32.BatteryLifePercent=255,windows,windows-7-x64,jna,battery,kernel32,Windows,Windows 7 X64,Jna,Battery,Kernel32,我正在尝试构建一个Java应用程序,它可以读取笔记本电脑电池的状态,并在电池电量不足时向用户发送通知。为了做到这一点,我将jna与Kernel32本机库一起使用,如问题的第一个答案所述: 运行该示例时,程序将生成以下输出: ACLineStatus: Offline Battery Flag: High, more than 66 percent Battery Life: Unknown Battery Left: 0 seconds Battery Full: 10832 seconds

我正在尝试构建一个Java应用程序,它可以读取笔记本电脑电池的状态,并在电池电量不足时向用户发送通知。为了做到这一点,我将jna与Kernel32本机库一起使用,如问题的第一个答案所述:

运行该示例时,程序将生成以下输出:

ACLineStatus: Offline
Battery Flag: High, more than 66 percent
Battery Life: Unknown
Battery Left: 0 seconds
Battery Full: 10832 seconds
字段battery life和battery left在Kernel32 BatteryLifePercent和BatteryLifeTime值中读取,这两个值分别为255(未知)和0(我没有得到此值。根据Microsoft文档,未知值将为-1: )

我的问题是:为什么我要找回这些值?Windows电池托盘图标显示正确的百分比,为什么我不能从这里获取数据

我运行的是64位Windows7终极版


多谢各位

链接答案中的代码错误(编辑):现在 它是固定的)

字段顺序错误,请使用更改
getFieldOrder
方法

@Override
protected List<String> getFieldOrder() 
{
    ArrayList<String> fields = new ArrayList<String>();
    fields.add("ACLineStatus");
    fields.add("BatteryFlag");
    fields.add("BatteryLifePercent");
    fields.add("Reserved1");
    fields.add("BatteryLifeTime");
    fields.add("BatteryFullLifeTime");
    return fields;
}
对齐方式也可以是
ALIGN\u NONE
,因为Microsoft通常会注意将数据与保留字段显式对齐。
它也可以是
ALIGN\u DEFAULT
,因为据我所知,Windows是用Microsoft编译器编译的,它将数据与自然边界对齐

换句话说,结构通过设计自然对齐,因此不需要特定的对齐约束


在我的系统上,这是原始代码的输出

A线路状态:离线
电池标志:高,超过66%
电池寿命:未知
电池剩余时间:0秒
电池电量:12434秒

这是带有更正代码的输出

A线路状态:离线
电池标志:高,超过66%
电池寿命:95%
电池剩余时间:12434秒
电池已满:未知


为什么会这样 考虑到上面的输出,我们可以重建结构
系统电源状态
在内存中的填充方式

    00 08 5f 00 96 30 00 00 ff ff ff ff
    ¯¯ ¯¯ ¯¯ ¯¯ ¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯
     |  | |  |          |             |   
     |  | |  |       BatteryLifeTime  |
     |  | | Reserved1                 |
     |  | |                      BatteryFullLifeTime     
     |  | BatteryLifePercent
     |  |
     | BatteryFlags
     |
 AcLineStatus
根据原始代码的字段顺序,字段是如何初始化的

    00 08 5f 00 96 30 00 00 ff ff ff ff  00 00 00 00
    ¯¯ ¯¯       ¯¯¯¯¯¯¯¯¯¯¯ ¯¯           ¯¯¯¯¯¯¯¯¯¯¯
    |  |             |      |                    |
    | BatteryFlags   |     BatteryLifePercent    |
    |                |                           |
AcLineStatus         |                         BatteryLifeTime
                 BatteryFullLifeTime
间隙是由于在其自然边界上对齐数据的默认对齐方式造成的。
由于字段已重新排序,因此它们不再处于原始位置且连续

为什么电池寿命是未知的 如果您为Win7 64位反汇编函数
GetSystemPowerStatus
(您可以找到我的反汇编)并重写一个等效的C程序,您会得到如下结果

BOOL WINAPI GetSystemPowerStatus(
_输出系统电源状态系统电源状态
)
{
系统电池状态电池状态;
//获取电源信息
NTStatus pi_status=NtPowerInformation(SystemBatteryState、NULL、0和battery_state、sizeof(battery_state));
//检查成功
如果(!NTSuccess(pi_状态))
{
BaseSetLastInteror(pi_状态);
返回FALSE;
}
//将输入结构归零
memset(lpSystemPowerStatus,sizeof(lpSystemPowerStatus),0;
//设置交流线路状态
lpSystemPowerStatus->ACLineStatus=battery\u state.BatteryPresent&&battery\u state.AcOnLine?1:0;
//设旗
lpSystemPowerStatus->BatteryFlags |=(电池状态。充电?8:0)
|(电池状态。电池当前?0:0x80);
//设置电池寿命百分比
lpSystemPowerStatus->BatteryLifePercent=0xff;
if(电池状态。最大容量)
{
lpSystemPowerStatus->BatteryLifePercent=电池\状态.RemainingCapacity>电池\状态.MaxCapacity
? 100
:(电池状态。剩余容量*100+电池状态。最大容量/2)/电池状态。最大容量;
lpSystemPowerStatus->BatteryFlags |=(lpSystemPowerStatus->BatteryLifePercent>66?1:0)
|(lpSystemPowerStatus->电池寿命百分比<33?2:0);
}
//设置电池寿命时间和全寿命时间
lpSystemPowerStatus->BatteryLifeTime=lpSystemPowerStatus->BatteryFullLifeTime=-1;
if(电池状态估计时间)
lpSystemPowerStatus->BatteryLifeTime=电池\状态.EstimatedTime;
}
这表明
batterfulllife
从未从
SYSTEM\u BATTERY\u STATE
结构复制。它总是-1。
此外,从未设置值为4(临界电池电量)的标志。
在较新版本的Windows中,这些可能已经修复


新版本 您可以在
PowrProf.dll
中调用
CallNtPowerInformation
,以获取有关电池状态的更可靠信息

如果您不熟悉访问WinAPI,这里有一个JNA类为您完成这项工作

powrpof.Java

/*
*要更改此许可证标题,请在“项目属性”中选择“许可证标题”。
*要更改此模板文件,请选择工具|模板
*然后在编辑器中打开模板。
*/
包javaapplication5;
/**
*
*@作者mijo
*/
导入java.util.List;
导入com.sun.jna.Native;
导入com.sun.jna.Pointer;
导入com.sun.jna.Structure;
导入com.sun.jna.win32.StdCallLibrary;
导入java.util.array;
扩展StdCallLibrary的公共接口{
public powrpof INSTANCE=(powrpof)Native.loadLibrary(“powrpof”,powrpof.class);
公共类系统\电池\状态扩展结构
{
公共静态类ByReference扩展系统\电池\状态实现结构。ByReference{}
公共电话线;
公共字节表示;
公共字节收费;
公共场所;
公共字节Spare1_0;
公共字节Spare1_1;
公共字节Spare1_2;
公共字节Spare1_3;
公共int最大容量;
公共剩余能力;
    00 08 5f 00 96 30 00 00 ff ff ff ff  00 00 00 00
    ¯¯ ¯¯       ¯¯¯¯¯¯¯¯¯¯¯ ¯¯           ¯¯¯¯¯¯¯¯¯¯¯
    |  |             |      |                    |
    | BatteryFlags   |     BatteryLifePercent    |
    |                |                           |
AcLineStatus         |                         BatteryLifeTime
                 BatteryFullLifeTime