获取电池设备名称

时间:2013-02-08 22:34:06

标签: c++ winapi battery

我正在尝试使用此代码获取计算机上所有电池设备的名称,这些代码主要是从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请帮助

1 个答案:

答案 0 :(得分:3)

问题在于,您对DeviceIoControl的调用是错误的。你正在扔垃圾,当你把垃圾放进去的时候就会把垃圾扔掉。

string bi;

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

您正在将std::string对象的地址传递给DeviceIoControlstd::stringstd::string一无所知,并期望可以写入的原始缓冲区的地址。您至少为该缓冲区指定了正确的大小,但即便如此也是错误的。基本上,当该函数返回时,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)) 是垃圾并且访问它可以做任何事情 - 从崩溃程序到在扬声器上播放Vivaldi。

尝试这样的事情:

{{1}}