以获取笔记本电池信息为例介绍WMI的使用

news2024/10/3 0:35:07

注:本人也还没有完全弄懂WMI的原理,以下内容仅供参考。。。
在这里插入图片描述

简单来说,比起Win32提供的接口,WMI可以提供更多的系统信息,它本身是一个数据库架构,通过它可以访问、配置、管理和监视几乎所有的Windows资源,比如用户可以在远程计算机上启动一个进程。

例如,如果我想调取笔记本的电量信息,用Win32的api就只能获得以下几个参数:

typedef struct _SYSTEM_POWER_STATUS {
  BYTE  ACLineStatus; // AC电源状态
  BYTE  BatteryFlag; // 电池充电状态
  BYTE  BatteryLifePercent; // 剩余电池电量的百分比
  BYTE  SystemStatusFlag; // 节电器的状态
  DWORD BatteryLifeTime; // 剩余电量的秒数
  DWORD BatteryFullLifeTime; // 完全充电时的电池运行时间的秒数
} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;

官方文档链接:https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status

而使用WMI,可以获得多得多的信息:

[Dynamic, Provider("CIMWin32"), UUID("{8502C4B9-5FBB-11D2-AAC1-006008C78BC7}"), AMENDMENT]
class Win32_Battery : CIM_Battery
{
  uint16   Availability;
  uint32   BatteryRechargeTime;
  uint16   BatteryStatus;
  string   Caption;
  uint16   Chemistry;
  uint32   ConfigManagerErrorCode;
  boolean  ConfigManagerUserConfig;
  string   CreationClassName;
  string   Description;
  uint32   DesignCapacity;
  uint64   DesignVoltage;
  string   DeviceID;
  boolean  ErrorCleared;
  string   ErrorDescription;
  uint16   EstimatedChargeRemaining;
  uint32   EstimatedRunTime;
  uint32   ExpectedBatteryLife;
  uint32   ExpectedLife;
  uint32   FullChargeCapacity;
  datetime InstallDate;
  uint32   LastErrorCode;
  uint32   MaxRechargeTime;
  string   Name;
  string   PNPDeviceID;
  uint16   PowerManagementCapabilities[];
  boolean  PowerManagementSupported;
  string   SmartBatteryVersion;
  string   Status;
  uint16   StatusInfo;
  string   SystemCreationClassName;
  string   SystemName;
  uint32   TimeOnBattery;
  uint32   TimeToFullCharge;
};

官方文档链接:
https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-battery

接下来在VS中,用C++来使用WMI:

#define _WIN32_DCOM

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

using namespace std;



int main(int argc, char** argv) {
    HRESULT hres;

    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        cout << "Failed to initialize COM library. Error code = 0x"
            << hex << hres << endl;
        return 1;                  // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------

    hres = CoInitializeSecurity(
        NULL,
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
    );


    if (FAILED(hres)) {
        cout << "Failed to initialize security. Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;                    // Program has failed.
    }

    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    IWbemLocator* pLoc = NULL;

    hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator, (LPVOID*)&pLoc);

    if (FAILED(hres)) {
        cout << "Failed to create IWbemLocator object."
            << " Err code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;                 // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices* pSvc = NULL;

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
        NULL,                    // User name. NULL = current user
        NULL,                    // User password. NULL = current
        0,                       // Locale. NULL indicates current
        NULL,                    // Security flags.
        0,                       // Authority (for example, Kerberos)
        0,                       // Context object 
        &pSvc                    // pointer to IWbemServices proxy
    );

    if (FAILED(hres)) {
        cout << "Could not connect. Error code = 0x"
            << hex << hres << endl;
        pLoc->Release();
        CoUninitialize();
        return 1;                // Program has failed.
    }

    cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
    );

    if (FAILED(hres)) {
        cout << "Could not set proxy blanket. Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_Battery"), // 改类名
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres)) {
        cout << "Query for operating system name failed."
            << " Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;

    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);

        if (0 == uReturn) {
            break;
        }

        VARIANT vtProp;

        VariantInit(&vtProp);
        // Get the value of the Name property
        hr = pclsObj->Get(L"Chemistry", 0, &vtProp, 0, 0); // 改成员变量
        wcout << " Chemistry : " << vtProp.intVal << endl; // 改变量值的类型
        VariantClear(&vtProp);

        pclsObj->Release();
    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return 0;   // Program successfully completed.

}

控制台输出:

Connected to ROOT\CIMV2 WMI namespace
Chemistry : 6
D:\VSProject\demo1\Project1\x64\Debug\Project1.exe (process 9504) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . . 

说明我的笔记本用的是锂电池。

如果想要获得其他参数,改三个地方就可以了。

  • 128行的Win32_Battery
  • 161行的Chemistry
  • 162行的intVal

官方C++使用WMI的帮助文档:
https://learn.microsoft.com/en-us/windows/win32/wmisdk/example–getting-wmi-data-from-the-local-computer

原理分析:

WMI的架构图如下:
在这里插入图片描述

根据上图,作为顶层使用人员,可以有三种方式调取WMI数据库的结构:

  • 使用C++
  • 使用命令行shell
  • 使用.NET客户端应用

也可以在命令行中直接敲命令,更简单:

PS C:\Users\Double Q> Get-WmiObject -Class Win32_Battery


__GENUS                     : 2
__CLASS                     : Win32_Battery
__SUPERCLASS                : CIM_Battery
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_Battery.DeviceID="1Desay*******9ECW-41"
__PROPERTY_COUNT            : 33
__DERIVATION                : {CIM_Battery, CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                    : LAPTOP-*********
__NAMESPACE                 : root\cimv2
__PATH                      : \\LAPTOP-********\root\cimv2:Win32_Battery.DeviceID="1Desay********ECW-41"
Availability                : 3
BatteryRechargeTime         :
BatteryStatus               : 1
Caption                     : 内部电池
Chemistry                   : 6
ConfigManagerErrorCode      :
ConfigManagerUserConfig     :
CreationClassName           : Win32_Battery
Description                 : 内部电池
DesignCapacity              :
DesignVoltage               : 14945
DeviceID                    : 1Desay********ECW-41
ErrorCleared                :
ErrorDescription            :
EstimatedChargeRemaining    : 44
EstimatedRunTime            : 85
ExpectedBatteryLife         :
ExpectedLife                :
FullChargeCapacity          :
InstallDate                 :
LastErrorCode               :
MaxRechargeTime             :
Name                        : ********ECW-41
PNPDeviceID                 :
PowerManagementCapabilities : {1}
PowerManagementSupported    : False
SmartBatteryVersion         :
Status                      : OK
StatusInfo                  :
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : LAPTOP-********
TimeOnBattery               :
TimeToFullCharge            :
PSComputerName              : LAPTOP-********

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/397461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AM5728(AM5708)开发实战之移植OpenCV-3.4.11

一 概述 OpenCV是一个开源的跨平台计算机视觉库&#xff0c;可以运行在Linux、Windows、Mac OS等操作系统上&#xff0c;它为图像处理、模式识别、三维重建、物体跟踪、机器学习提供了丰富的算法。 由于OpenCV依赖包特别多&#xff0c;尽量不要使用交叉编译&#xff0c;即在什…

VMware虚拟机搭建环境通用方法

目录一、前期准备1.下载并安装一个虚拟机软件二、开始创建虚拟机1.配置虚拟机硬件相关操作2.虚拟机网络相关操作三、开机配置相关内容0.开机遇到报错处理&#xff08;选看--开机没有报错请忽略&#xff09;1.开始配置2.开机之后配置3.使用xshell远程登录4.使用xshell配置虚拟机…

下一个7年,保持期待、持续思考,酷雷曼继续向前!

过去7年&#xff0c;我们一直在思考&#xff0c; VR技术究竟能为我们的生活带来什么&#xff1f; 是足不出户就能云游千里的秀美风光&#xff1f; 是在家就能沉浸式体验线上消费的便利&#xff1f; 还是为商企和用户搭建更快速的沟通桥梁&#xff1f; NO.1、技术变革 在信…

磁盘阵列Raid探讨

最近公司买服务器&#xff0c;顺便了解一下服务器配置方面的问题 以下讨论的都是入门级服务器配置&#xff0c;全部是主观意见&#xff0c;没有任何科学依据&#xff0c;欢迎大家讨论 Raid0&#xff0c;Raid1&#xff0c;Raid10&#xff0c;Raid5&#xff0c;Raid6(Raid5热备)…

计算机科学导论笔记(四)

目录 六、计算机网络和因特网 6.1 引言 6.1.1 网络 6.1.2 因特网 6.1.3 硬件和软件 6.1.4 协议分层 6.1.5 TCP/IP协议族 6.2 应用层 6.2.1 应用层模式 6.2.2 标准客户机-服务器应用 6.2.3 文件传输协议&#xff08;FTP&#xff09; 6.2.4 电子邮件 6.2.5 TELNET 6…

vue 模拟 chatgpt 聊天效果:js 实现逐字显示、延时函数模拟对话

vue 模拟 chatgpt 聊天效果&#xff1a;js 实现逐字显示、延时函数模拟对话模拟 chatgpt 聊天功能&#xff0c;展示对话效果。其中比较有意义的技术点是&#xff1a;js 实现逐字显示、延时函数&#xff0c;同步遍历。 <template><div class"chat-gpt">…

SpringBoot中的bean注入方式和原理介绍

Spring Boot是一个非常流行的Java框架&#xff0c;它可以帮助开发者快速地构建高效、健壮的应用程序。其中一个重要的功能就是依赖注入&#xff0c;也就是将一个对象注入到另一个对象中&#xff0c;以便它们可以相互协作。在Spring Boot中&#xff0c;依赖注入是通过bean实现的…

易优cms 标签常用函数

【基础用法】 标签&#xff1a;无 描述&#xff1a;作用于标签变量 用法&#xff1a; {$field.typename|html_msubstr###,0,10,true} 注意&#xff1a;函数与字段名之间用竖线&#xff08;|&#xff09;隔开&#xff0c;###表示当前变量 属性&#xff1a; 无 涉及表字段…

Kafka 消费进度

Kafka 消费进度Kafka 自带命令Java Consumer APIJMX 监控指标监控消费进度 : 看滞后程度&#xff1a;消费者 Lag , Consumer Lag 滞后程度 : 消费者落后于生产者的程度 如 : Kafka 生产者向某主题成功生产 100 万条消息&#xff0c;消费者消费 80 万条消息那消费者就滞后 20 …

ccc-pytorch-卷积神经网络实战(6)

文章目录一、CIFAR10 与 lenet5二、CIFAR10 与 ResNet一、CIFAR10 与 lenet5 第一步&#xff1a;准备数据集 lenet5.py import torch from torch.utils.data import DataLoader from torchvision import datasets from torchvision import transformsdef main():batchsz 128C…

基于嵌入式libxml2的ARM64平台的移植(aarch64)

由于libxml在移植过程中依赖于zlib的库文件&#xff0c;因此本节内容包含zlib&#xff08;V1.2.13&#xff09;的移植libxml2(V2.10.3)的移植两部分组成。 &#xff08;一&#xff09;zlib的移植&#xff08;基于arm64&#xff09; 1、在github上下载zlib的最新源码压缩包&am…

【C++的OpenCV】第十课-OpenCV图像常用操作(七):直方图和直方图同等化(直方图均衡化)

&#x1f389;&#x1f389;&#x1f389;欢迎各位来到小白piao的学习空间&#xff01;\color{red}{欢迎各位来到小白piao的学习空间&#xff01;}欢迎各位来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496;&#x1f496;&#x1f496…

看完书上的链表还不会实现?不进来看看?

1.1链表的概念定义&#xff1a;链表是一种物理存储上非连续&#xff0c;数据元素的逻辑顺序通过链表中的指针链接次序&#xff0c;实现的一种线性存储结构。特点&#xff1a;链表由一系列节点组成&#xff0c;节点在运行时动态生成 &#xff08;malloc&#xff09;&#xff0c;…

【react】类组件

React类创建组件&#xff0c;通过继承React内置的Component来实现的 class MyComponent extends React.Component{render() {console.log(this)// render是放在哪里的 —— 类(即&#xff1a;MyComponent)的原型对象上&#xff0c;供实例使用return <h2>我是用函数定义的…

python实现波士顿房价预测

波士顿房价预测 目标 这是一个经典的机器学习回归场景&#xff0c;我们利用Python和numpy来实现神经网络。该数据集统计了房价受到13个特征因素的影响&#xff0c;如图1所示。 对于预测问题&#xff0c;可以根据预测输出的类型是连续的实数值&#xff0c;还是离散值&#xff…

QGraphicsItem的简单自定义图形项

QGraphicsItem的继承重写序言重点函数QRectF boundingRect() constQPainterPath shape() constvoid paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget 0)序言 学习途中记录一下&#xff0c;可谓是精华点 重点函数 QRectF boundingRect()…

农产品销售系统/商城,可运行

文章目录项目介绍一、项目功能介绍1、用户模块主要功能包括&#xff1a;2、商家模块主要功能包括&#xff1a;3、管理员模块主要功能包括&#xff1a;二、部分页面展示1、用户模块部分功能页面展示2、商家模块部分功能页面展示3、管理员模块部分功能页面展示三、部分源码四、底…

蓝牙 - 设备类型设置: Class of Device

在电脑或手机上&#xff0c;搜寻和连接蓝牙设备时&#xff0c;不同的蓝牙设备显示的图标是不同的&#xff0c;比如搜到或连接上的设备是一个蓝牙键盘&#xff0c;显示的就会是键盘图标&#xff0c;如果搜索到的设备是一个手柄&#xff0c;显示的就是一个手柄图标。 显示的图标是…

进程(操作系统408)

进程的概念和特征 概念&#xff1a; 进程的多个定义&#xff1a; 进程是程序的一次执行过程 进程是一个程序及其数据在处理机上顺序执行时所发生的活动 进程时具有独立功能的程序在一个数据集合上运行的过程&#xff0c;它是系统进行资源分配和调度的一个独立单位 上面所说…

JVM的基本知识

JVM JVM是java的虚拟机,是一个十分复杂的东西,所以掌握的要求比较高.本文主要是研究JVM的三大话题 JVM内存划分JVM类加载JVM的垃圾回收 JVM内存划分 java程序要执行的时候,JVM会先申请一块空间,这里就涉及到JVM的内存划分 堆 : 放的是new 出来的对象栈: 放的是方法之间的调…