获取电池设备名称

Get battery device name

本文关键字:设备名 获取      更新时间:2023-10-16

我正在尝试使用此代码获取计算机上所有电池设备的名称,这些代码主要从Microsoft教程中获取,但它不起作用。

#define INITGUID
#include <windows.h>
#include<batclass.h>
#include<setupapi.h>
#define GBS_HASBATTERY 0x1
#define GBS_ONBATTERY  0x2
#include<iostream>
using namespace std;
int main()
{
DWORD dwResult = GBS_ONBATTERY;
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVICE_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
for (int idev = 0; idev < 100; idev++)
 {
  SP_DEVICE_INTERFACE_DATA did = {0};
  did.cbSize = sizeof(did);
  if (SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVICE_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)
             {////////////////////////////////////////problem around here///////
              string  bi;
              bqi.InformationLevel = BatteryDeviceName;
              if (DeviceIoControl(hBattery,
                                  IOCTL_BATTERY_QUERY_INFORMATION,
                                  &bqi,
                                  sizeof(bqi),
                                  &bi,
                                  sizeof(bi),
                                  &dwOut,
                                  NULL))
            {
                cout<<bi;
                  BATTERY_WAIT_STATUS bws = {0};
                  bws.BatteryTag = bqi.BatteryTag;
                  BATTERY_STATUS bs;
                  if (DeviceIoControl(hBattery,
                                      IOCTL_BATTERY_QUERY_STATUS,
                                      &bws,
                                      sizeof(bws),
                                      &bs,
                                      sizeof(bs),
                                      &dwOut,
                                      NULL))
                   {
                    if (bs.PowerState & BATTERY_POWER_ON_LINE)
                     {
                      dwResult &= ~GBS_ONBATTERY;
                     }
                   }
               }
             }
            CloseHandle(hBattery);
           }
         }
        LocalFree(pdidd);
       }
     }
   }
    else  if (ERROR_NO_MORE_ITEMS == GetLastError())
     {
      break;
     }
 }
SetupDiDestroyDeviceInfoList(hdev);
}

我正在尝试打印所有电池的名称,但是当我运行该程序时,它根本不打印任何内容,但是当我请求battery_information结构而不是字符串 BatteryDeviceName 时,它确实有效,请帮助

问题是你打电话给DeviceIoControl是错误的。你正在传递垃圾,当你把垃圾放进去时,你就会把垃圾扔出来。

string bi;
if(DeviceIoControl(hBattery,
                   IOCTL_BATTERY_QUERY_INFORMATION,
                   bqi,
                   sizeof(bqi),
                   &bi,         // Really?!?!?!
                   sizeof(bi),  // WHAT?!?
                   &dwOut,
                   NULL))

您正在将地址传递给std::string对象DeviceIoControl,该对象对std::string一无所知,并期望它可以写入的原始缓冲区的地址。您至少为该缓冲区指定了正确的大小,但即使这样在某种意义上也是错误的。基本上,当该函数返回时,该std::string是垃圾,访问它可以做任何事情 - 从崩溃程序到在扬声器上播放 Vivaldi。

尝试这样的事情:

WCHAR szBuf[_MAX_PATH] = { 0 }; // In a real program you'd dynamically 
                                // allocate an appropriately sized buffer
                                // instead. 
if(DeviceIoControl(hBattery,
                       IOCTL_BATTERY_QUERY_INFORMATION,
                       bqi,
                       sizeof(bqi),
                       szBuf,
                       sizeof(szBuf),
                       &dwOut,
                       NULL))