获取电池状态(Win32, C++)

74 篇文章 1 订阅
5 篇文章 0 订阅
#include <iostream>

#include <guiddef.h>
#include <windows.h>
#include <powrprof.h>
#include <SetupAPI.h>
#include <Batclass.h>

#pragma comment(lib, "powrprof.lib")
#pragma comment(lib, "Setupapi.lib")

DEFINE_GUID(GUID_DEVCLASS_BATTERY,
	0x72631E54, 0x78A4, 0x11D0, 0xBC, 0xF7, 0x00, 0xAA, 0x00, 0xB7, 0xB3, 0x2A);

BATTERY_STATUS GetBatteryState(void)
{
    BATTERY_STATUS batteryStatus = { 0 };
    HDEVINFO hdev = ::SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (INVALID_HANDLE_VALUE != hdev)
    {
        //搜索限制为最多 100 块电池
        for (int idev = 0; idev < 100; idev++)
        {
            SP_DEVICE_INTERFACE_DATA did = { 0 };
            did.cbSize = sizeof(did);

            if (::SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVCLASS_BATTERY, idev, &did))
            {
                DWORD cbRequired = 0;

                ::SetupDiGetDeviceInterfaceDetail(hdev, &did, 0, 0, &cbRequired, 0);
                if (ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
                {
                    PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::LocalAlloc(LPTR, cbRequired);
                    if (pdidd)
                    {
                        pdidd->cbSize = sizeof(*pdidd);
                        if (::SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0))
                        {
                            // 枚举电池, 索取信息
                            HANDLE hBattery = ::CreateFile(pdidd->DevicePath,
                                GENERIC_READ | GENERIC_WRITE,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                NULL,
                                OPEN_EXISTING,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);
                            if (INVALID_HANDLE_VALUE != hBattery)
                            {
                                // 向电池索取标签.
                                BATTERY_QUERY_INFORMATION bqi = { 0 };

                                DWORD dwWait = 0;
                                DWORD dwOut;

                                if (::DeviceIoControl(hBattery,
                                    IOCTL_BATTERY_QUERY_TAG,
                                    &dwWait,
                                    sizeof(dwWait),
                                    &bqi.BatteryTag,
                                    sizeof(bqi.BatteryTag),
                                    &dwOut,
                                    NULL)
                                    && bqi.BatteryTag)
                                {
                                    //查询电池状态
                                    BATTERY_WAIT_STATUS bws = { 0 };
                                    bws.BatteryTag = bqi.BatteryTag;
                                    BATTERY_STATUS bs = { 0 };

                                    if (::DeviceIoControl(hBattery,
                                        IOCTL_BATTERY_QUERY_STATUS,
                                        &bws,
                                        sizeof(bws),
                                        &bs,
                                        sizeof(bs),
                                        &dwOut,
                                        NULL))
                                    {
                                        batteryStatus.Capacity = bs.Capacity;
                                        batteryStatus.PowerState = bs.PowerState;
                                        batteryStatus.Voltage = bs.Voltage;
                                        batteryStatus.Rate = bs.Rate;
                                    }
                                }
                                ::CloseHandle(hBattery);
                            }
                        }
                        ::LocalFree(pdidd);
                    }
                }
            }
            else  if (ERROR_NO_MORE_ITEMS == ::GetLastError())
            {
                break;
            }
        }
        ::SetupDiDestroyDeviceInfoList(hdev);
    }

    return batteryStatus;
}

int main()
{
    LONG ntStatus = S_OK;
    SYSTEM_BATTERY_STATE pi = { 0 };

    ntStatus = CallNtPowerInformation(SystemBatteryState, NULL, 0, &pi, sizeof(pi));
    if (0 == ntStatus)
    {
        printf("Battery: %d / %d\n", pi.RemainingCapacity, pi.MaxCapacity);
    }

    BATTERY_STATUS bs = GetBatteryState();
    printf("Capacity: %d mWh PowerState: %d Voltage: %d mv Rate: %d mWh\n", bs.Capacity, bs.PowerState, bs.Voltage, bs.Rate);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值