Aur*_*ere 3 windows battery jna windows-7-x64 kernel32
我正在尝试构建一个 Java 应用程序,该应用程序读取笔记本电脑电池的状态,并在电量不足时向用户发送通知。为了做到这一点,我将 jna 与 Kernel32 本机库一起使用,如该问题的第一个答案中所述: 如何在 Windows 系统中获得剩余电池寿命?
运行示例,程序产生以下输出:
ACLineStatus: Offline
Battery Flag: High, more than 66 percent
Battery Life: Unknown
Battery Left: 0 seconds
Battery Full: 10832 seconds
Run Code Online (Sandbox Code Playgroud)
电池寿命和电池剩余字段在 Kernel32 BatteryLifePercent和BatteryLifeTime值中读取,它们是 255(未知)和 0(我没有得到这个值。根据此处的 Microsoft 文档,未知将为 -1:https : //msdn.microsoft .com/en-us/library/windows/desktop/aa373232(v=vs.85).aspx )。
我的问题是:为什么我要取回这些值?Windows 电池托盘图标显示正确的百分比,那么为什么我无法从这里获取该数据?
我正在运行 64 位 Windows 7 Ultimate Edition。
谢谢你。
链接答案中的代码是错误的(编辑:现在已修复)。
字段以错误的方式排序,更改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;
}
Run Code Online (Sandbox Code Playgroud)
还要添加此构造函数以指定正确的对齐方式
public SYSTEM_POWER_STATUS()
{
setAlignType(ALIGN_MSVC);
}
Run Code Online (Sandbox Code Playgroud)
对齐方式也可能是ALIGN_NONE因为 Microsoft 通常会注意将数据与保留字段显式对齐。
也可能是ALIGN_DEFAULT因为,据我所知,Windows 是用 Microsoft 编译器编译的,并且它在自然边界上对齐数据。
换句话说,该结构是通过设计自然对齐的,因此它不需要特定的对齐约束。
这是我系统上原始代码的输出
ACLineStatus:离线
电池标志:高,超过 66%
电池寿命:未知
电池剩余时间:0 秒
电池充满:12434 秒
这是带有更正代码的输出
ACLineStatus:离线
电池标志:高,超过 66%
电池寿命:95%
剩余电量:12434 秒
电池已满:未知
考虑到上面的输出,我们可以重构结构SYSTEM_POWER_STATUS在内存中的填充方式。
00 08 5f 00 96 30 00 00 ff ff ff ff
¯¯ ¯¯ ¯¯ ¯¯ ¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯
| | | | | |
| | | | BatteryLifeTime |
| | | Reserved1 |
| | | BatteryFullLifeTime
| | BatteryLifePercent
| |
| BatteryFlags
|
AcLineStatus
Run Code Online (Sandbox Code Playgroud)
根据原始代码的字段顺序,这就是字段的初始化方式
00 08 5f 00 96 30 00 00 ff ff ff ff 00 00 00 00
¯¯ ¯¯ ¯¯¯¯¯¯¯¯¯¯¯ ¯¯ ¯¯¯¯¯¯¯¯¯¯¯
| | | | |
| BatteryFlags | BatteryLifePercent |
| | |
AcLineStatus | BatteryLifeTime
BatteryFullLifeTime
Run Code Online (Sandbox Code Playgroud)
间隙是由于在其自然边界上对齐数据的默认对齐方式造成的。
由于字段已重新排序,因此它们不再处于原始位置并且是连续的。
如果你反汇编GetSystemPowerStatusWin7 64 位的函数(你可以在这里找到我的反汇编)并重写一个等效的 C 程序,你会得到这样的东西
@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;
}
Run Code Online (Sandbox Code Playgroud)
这表明BatterFullLifeTime永远不会从SYSTEM_BATTERY_STATE结构中复制。它总是-1。
此外,永远不会设置值为 4(临界电池电量)的标志。
在较新版本的 Windows 中,这些可能已得到修复。
您可以拨打CallNtPowerInformation中PowrProf.dll获得关于电池状态更可靠的信息。
如果您不熟悉访问 Win API,这里有一个JNA类可以为您完成工作
职业教授Java
public SYSTEM_POWER_STATUS()
{
setAlignType(ALIGN_MSVC);
}
Run Code Online (Sandbox Code Playgroud)
以及它的用途
00 08 5f 00 96 30 00 00 ff ff ff ff
¯¯ ¯¯ ¯¯ ¯¯ ¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯
| | | | | |
| | | | BatteryLifeTime |
| | | Reserved1 |
| | | BatteryFullLifeTime
| | BatteryLifePercent
| |
| BatteryFlags
|
AcLineStatus
Run Code Online (Sandbox Code Playgroud)
放电时样品输出:
交流线?false
电池存在吗?true
电池流量:放电
最大容量 (mWh):35090
当前充电 (mWh):34160
流量 (mW/s):-11234
预计时间(来自操作系统):10940
预计时间(手动):10946
预计充满时间(手动)):-1
当前电量(百分比):97.34
当前电量(积分百分比):98
充电时输出示例:
交流线?true
电池存在吗?true
电池流量:充电
最大容量 (mWh):35090
当前充电 (mWh):33710
流量 (mW/s):3529
预计时间(来自操作系统):-1
预计时间(手动):-1
预计充满时间(手册):1407 当前电量(百分比):96.06
当前电量(积分百分比):97
NB插拔电源线进行测试时,请稍等片刻,因为监控不是实时的。
PS
我用化名Mijo签署我的代码,您可以删除该评论。
| 归档时间: |
|
| 查看次数: |
483 次 |
| 最近记录: |