zoukankan      html  css  js  c++  java
  • WMI系统管理工具介绍和获取机器码

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:

    https://www.cnblogs.com/bclshuai/p/11380657.html

    WMI系统管理工具获取机器码

     

    目录

    1      简介

    2      WMI结构流程

    3      WMI函数调用步骤和实例

    3.1     函数调用步骤

    3.2     获取代码实例

    4      高级查询

    1       简介

    WMI(Windows Management Instrumentation)是window系统管理工具,是一个提供信息查询的服务,可以在服务中查看。WMI简单的应用就是获取CPU序列号,硬盘序列号,网卡mac地址等。查询正在运行的进程、线程信息,查询环境变量、驱动信息、文件夹属性、系统信息、系统服务、本地用户和组、查询硬件信息等。高级应用是通过WMI脚本或者应用程序去管理本地或者远程计算机上的资源。

     

    WMI实际上是提供了一套标准规范的接口,提供给调用者使用,实现系统信息和资源的管理,它提供了一个通过操作系统、网络和企业环境去管理本地或远程计算机的统一接口集。不是直接通过调用系统API去访问,是因为系统API有些是不支持远程调用和脚本调用。WMI提供了通用化的接口。

           WMI支持WEBEM行业标准,WBEM即Web-Based Enterprise Management。WMI技术影响最大是其组件CIM和MOF。CIM是Common Information Modal,即公共信息模型。MOF是Managed Object Format,即托管对象格式。

    2       WMI结构流程

    如下图所示WMI相当于提供者和消费者之间的纽带,消费者调用WMI的API函数,去向提供者查询数据。

     

    WMI Consumers(WMI使用者)

    程序员通过各种形式,调用WMI的接口,请求查询数据。

    WMI Infrastructure(WMI基础结构)

    包含两个模块:包含WMI Core(WMI核心)的WMI Service(WMI服务)(Winmgmt)和WMI Repository(WMI存储库)。WMI存储库是通过WMI Namespace(WMI命名空间)组织起来的。在系统启动时,WMI服务会创建诸如rootdefault、rootcimv2和rootsubscription等WMI命名空间。通过访问这些命名空间去获取其下定义的数据。

    Managed object and WMI providers

    硬盘驱动器、网络适配器、数据库系统、操作系统、进程或者服务等提供者通过MOF托管对象格式向WMI提供数据。

    3       WMI函数调用步骤和实例

    3.1  函数调用步骤

    (1)   初始化COM based API

    CoInitializeEx(

        _In_opt_ LPVOID pvReserved,

        _In_ DWORD dwCoInit

        );

    (2)设置Com访问权限

    CoInitializeSecurity(

        _In_opt_ PSECURITY_DESCRIPTOR pSecDesc,

        _In_ LONG cAuthSvc,

        _In_reads_opt_(cAuthSvc) SOLE_AUTHENTICATION_SERVICE * asAuthSvc,

        _In_opt_ void * pReserved1,

        _In_ DWORD dwAuthnLevel,

        _In_ DWORD dwImpLevel,

        _In_opt_ void * pAuthList,

        _In_ DWORD dwCapabilities,

        _In_opt_ void * pReserved3

    );

    (3)创建本地comlocator对象连接WMI服务

    _Check_return_ HRESULT CoCreateInstance(

            _In_ REFCLSID rclsid,

            _Inout_opt_ LPUNKNOWN pUnkOuter = NULL,

            _In_ DWORD dwClsContext = CLSCTX_ALL) throw()

        {

            ATLASSERT(p == NULL);

            return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);

    }

    (4)连接WMI服务

       virtual HRESULT STDMETHODCALLTYPE ConnectServer(

                /* [in] */ const BSTR strNetworkResource,

                /* [in] */ const BSTR strUser,

                /* [in] */ const BSTR strPassword,

                /* [in] */ const BSTR strLocale,

                /* [in] */ long lSecurityFlags,

                /* [in] */ const BSTR strAuthority,

                /* [in] */ IWbemContext *pCtx,

                /* [out] */ IWbemServices **ppNamespace) = 0;

    (5)执行查询语句查询数据

    virtual HRESULT STDMETHODCALLTYPE ExecQuery(

                /* [in] */ __RPC__in const BSTR strQueryLanguage,

                /* [in] */ __RPC__in const BSTR strQuery,

                /* [in] */ long lFlags,

                /* [in] */ __RPC__in_opt IWbemContext *pCtx,

                /* [out] */ __RPC__deref_out_opt IEnumWbemClassObject **ppEnum) = 0;

    3.2  获取代码实例

    // WmiConnect.cpp : Defines the entry point for the console application.

    //

     

    #include "stdafx.h"

    #include <atlcomcli.h>//CComPtr

    #include <Wbemidl.h>

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

    #include<iostream>

    #include <sstream>

    #define SQL_BUFF_SIZE 256

    LPCWSTR const NETWORK_ADAPTER = L"Win32_NetworkAdapter";

    LPCWSTR const BASE_BOARD = L"Win32_BaseBoard";

    LPCWSTR const WIN32_CPU = L"Win32_Processor";

    LPCWSTR const DISK_DRIVE = L"Win32_DiskDrive";

    using namespace std;

    //web服务对象

    CComPtr<IWbemServices> m_spWbemServices = NULL;

    //去除空格函数

    void Trim(char* buf, size_t iSize, char cFlag)

    {

        if (NULL == buf || iSize <= 0)

        {

            return;

        }

        //寻找前面的

        size_t iStart = 0, iEnd = 0;

        for (iStart = 0; iStart < iSize; iStart++)

        {

            if (buf[iStart] != cFlag)

            {

                 break;

            }

        }

        if (iStart >= iSize)//全是

        {

            buf[0] = '';

            return;

        }

     

        //寻找后面的,发现要去除的符号时,直接改为字符结束符

        for (iEnd = iSize - 2; iEnd >= iStart; iEnd--)//排除结束符

        {

            if (buf[iEnd] != cFlag)

            {

                 break;

            }

            else

            {

                 buf[iEnd] = '';

            }

        }

     

        if (iEnd < 0)//全是

        {

            buf[0] = '';

            return;

        }

     

        if (iStart == 0)//前面没有要去除的符号时

        {

            return;

        }

     

        //移动数据

        size_t i = 0;

        for (size_t j = iStart; i <= iEnd - iStart; i++, j++)

        {

     

            buf[i] = buf[j];

        }

        buf[i] = '';//添加字符串结束标识

     

    }

     

    void Trim(string &str, char cFlag)

    {

        if (str.length() == 0)

        {

            return;

        }

        if (str == " ")

        {

            str = "";

            return;

        }

        char *pBuf = new char[str.length() + 1];

        if (NULL != pBuf)

        {

            strcpy_s(pBuf, str.length() + 1, str.c_str());

            Trim(pBuf, str.length() + 1, cFlag);

            str = pBuf;

            delete[]pBuf;

        }

    }

    //将varValue变量转换为string

    void VTtoStr(CComVariant & varValue, string &str)

    {

        USES_CONVERSION;

        ostringstream oss;

        switch (varValue.vt)

        {

        case VT_I4:

            oss << varValue.lVal;

            break;

        case VT_I8:

            oss << varValue.llVal;

            break;

        case VT_I2:

            oss << varValue.iVal;

            break;

        case VT_UI1:

            oss << varValue.bVal;

            break;

        case VT_R4:

            oss << varValue.fltVal;

            break;

        case VT_R8:

            oss << varValue.dblVal;

            break;

        case VT_I1:

            oss << varValue.cVal;

            break;

        case VT_UI2:

            oss << varValue.uiVal;

            break;

        case VT_UI4:

            oss << varValue.ulVal;

            break;

        case VT_UI8:

            oss << varValue.ullVal;

            break;

        case VT_BOOL:

            oss << varValue.boolVal;

            break;

        case  VT_BSTR:

            oss << OLE2A(varValue.bstrVal);

            break;

        case VT_EMPTY:

            oss << "VT_EMPTY";

            break;

        case VT_CY:

            oss << "VT_CY";

            break;

        case VT_NULL:

            oss << "VT_NULL";

            break;

        case VT_DATE:

            oss << "VT_DATE";

            break;

        default:

            oss << (varValue.ChangeType(VT_BSTR) == S_OK) ? OLE2A(varValue.bstrVal) : "Cannot handle the the data type";

            break;

        }

        str = oss.str();

        Trim(str,' ');

    }

    //从查询的数据中获取属性值

    string GetProperty(IWbemClassObject *pClassObject, LPCWSTR wsName)

    {

        USES_CONVERSION;

        CComVariant varValue;

        string str("");

        if (pClassObject->Get(wsName, 0, &varValue, NULL, 0) != S_OK)

        {

            //LOG_INFO("Get fail");

            return str;

        }

        // 对不同的数据类型分别处理

        if (varValue.vt == VT_ARRAY) //数组

        {

            long iLowBound = 0, iUpBound = 0, j = 0;

            SafeArrayGetLBound(varValue.parray, 1, &iLowBound);

            SafeArrayGetUBound(varValue.parray, 1, &iUpBound);

            for ( /*long*/ j = iLowBound; j <= iUpBound; j++)

            {

                 VARIANT *pvar = NULL;

                 long temp = j;

                 if (SafeArrayGetElement(varValue.parray, &temp, pvar) == S_OK && pvar)

                 {

                     CComVariant varTemp;

                     if (varTemp.ChangeType(VT_BSTR, pvar) == S_OK)

                     {

                         if (0 != str.length())

                         {

                             str.append(",");

                         }

                         str.append(OLE2A(varTemp.bstrVal));

                     } //if( varTemp...

                } //if( SafeArrayGet...

                 else

                 {

                     //LOG_INFO("SafeArrayGetElement fail pvar=%p", pvar);

                 }

            } //for( long j=iLowBound;...

        } //if (varValue.vt ...

        else

        {

            VTtoStr(varValue, str);

        }

    //  LOG_INFO("%s = %s", OLE2A(wsName), str.c_str());

        return str;

    }

    //执行查询语句

    bool ExecQuery(WCHAR* szSQL, CComPtr<IEnumWbemClassObject> &spEnumWbemClassObject)

    {

        if (m_spWbemServices->ExecQuery(L"WQL", szSQL, WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &spEnumWbemClassObject) != S_OK)

        {

            return false;

        }

        if (spEnumWbemClassObject->Reset() != S_OK)

        {

            return false;

        }

        return true;

    }

    BOOL GetWmiInfo(LPCWSTR lpszClass, LPCWSTR szProperty, string &szRet)

    {

        BOOL bRet = FALSE;

        CComPtr<IEnumWbemClassObject> spEnumWbemClassObject;

        wchar_t szSQL[SQL_BUFF_SIZE] = { 0 };

        swprintf_s(szSQL, SQL_BUFF_SIZE - 1, L"Select %s from %s", szProperty, lpszClass);

     

        if (!ExecQuery(szSQL, spEnumWbemClassObject))

        {

            return FALSE;

        }

     

        USES_CONVERSION;

        ULONG uCount = 1, uReturned = 0;

        CComPtr<IWbemClassObject> spClassObject;

     

        while (spEnumWbemClassObject->Next(WBEM_INFINITE, uCount, &spClassObject, &uReturned) == S_OK)

        {

            szRet = GetProperty(spClassObject, szProperty);

            bRet = szRet.length() == 0 ? FALSE : TRUE;

            spClassObject.Release();

     

        }

        return bRet;

    }

    int main()

    {

        HRESULT hResult;

        //初始化Com based API

        hResult = CoInitializeEx(0, COINIT_MULTITHREADED);

        if (FAILED(hResult))

        {

            cout << "Failed to initialize COM library. Error code = 0x"<< hex << hResult << endl;

            return 1; //

        }

        //设置Com访问权限

        hResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);

        if (S_OK != hResult && RPC_E_TOO_LATE != hResult)

        {

            cout<<"CoInitializeSecurity failed " << hResult<< endl;

            return 2;

        }

        //创建本地comlocator对象连接WMI服务

        CComPtr<IWbemLocator> pCom = NULL;

        hResult = pCom.CoCreateInstance(CLSID_WbemAdministrativeLocator, 0, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER);

        if (hResult != S_OK)

        {

            cout << "CoCreateInstance failed " << hResult << endl;

            CoUninitialize();

            return 3;

        }

        //连接WMI服务

        hResult = pCom->ConnectServer(L"root\cimv2", NULL, NULL, NULL, 0, NULL, NULL, &m_spWbemServices);

        if (hResult != S_OK)

        {

            cout << "ConnectServer failed " << hResult << endl;

            CoUninitialize();

            return 3;

        }

        string szRet = "";

        //获取数据

        GetWmiInfo(L"Win32_DiskDrive", L"SerialNumber", szRet);//硬盘序列号

        cout << szRet << endl;

        GetWmiInfo(L"Win32_BaseBoard", L"SerialNumber", szRet);//主板序列号

        cout << szRet << endl;

        GetWmiInfo(L"Win32_Processor", L"ProcessorId", szRet);//cpu编号

        cout << szRet << endl;

        GetWmiInfo(L"Win32_PhysicalMemory", L"SerialNumber", szRet);//物理内存序列号

        cout << szRet << endl;

        GetWmiInfo(L"Win32_NetworkAdapter", L"MACAddress", szRet);//mac地址

        cout << szRet << endl;

        system("pause");

     

    }

     

    输出结果

     

    4       高级查询

    参考文献:

    https://fangliang.blog.csdn.net/article/details/50644688?utm_medium=distribute.pc_relevant.none-task-blog-searchFromBaidu-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-searchFromBaidu-3.control

    通过上面的实例可以看到,通过初始化,创建COM对象,连接服务之后,就可以通过执行类似于SQL的语句去查询数据,所以只要知道怎么去组织这个查询语句,然后调用ExecQuery函数,就可以查询数据了。下面列举一些常规的查询语句。可以组合查询下面的属性,用逗号隔开,也可以查询满足条件的属性,和SQL语句一致。

    查询信息

    属性

    说明

    查询进程Win32_Process的属性

    SELECT Caption, ProcessId  FROM Win32_Process where processId=112313

    Caption

    名称

    ProcessId

    进程Id

    ParentProcessId

    父进程id

    CommandLine

    启动命令行

    CreationDate

    启动时间

    ExecutablePath

    进程路径

    UserModeTime

    用户时间

    KernelModeTime

    内核时间

    ThreadCount

    进程中线程数量

    Priority

    优先级

    查询线程的属性Win32_Thread

    SELECT * FROM Win32_Thread

    ElapsedTime

    线程占用时间

    Handle

    线程句柄

    KernelModeTime

    内核时间

    Priority

    优先级

    查询环境变量

    SELECT VariableValue FROM Win32_Environment WHERE SystemVariable = TRUE

    VariableValue

    变量值

    根据用户名查询用户桌面Win32_Desktop

    SELECT IconTitleSize FROM Win32_Desktop WHERE Name = 'Your Login Name’

    IconTitleFaceName

    桌面图标名称

    IconTitleSize

    字体大小

    查询驱动信息Win32_SystemDriver

    查询文件夹属性Win32_Directory

    查询磁盘分区Win32_DiskPartition和Win32_LogicalDisk

    查询系统属性Win32_ComputerSystem

    查询系统时间Win32_LocalTime和Win32_UTCTime

    查询服务Win32_Service

    查询组和用户Win32_Group和Win32_UserAccount

    查询主板信息Win32_BaseBoard

    查询硬盘信息Win32_DiskDrive

    查询内存信息Win32_MemoryDevice

    查询网卡信息Win32_NetworkAdapter

    查询CPU信息Win32_Processor

  • 相关阅读:
    nginx 负载均衡配置
    nginx 配置优化详解
    duilib -- Label控件的bug(转载)
    Duilib实现GroupBox控件
    Duilib动画按钮实现(转载)
    Duilib中Webbrowser事件完善使其支持判断页面加载完毕
    Duilib实现圆形头像控件
    duilibutilsutils.h(251) : error C2504: “VARIANT”: 未定义基类
    软件项目版本号的命名规则及格式
    c++中char*wchar_t*stringwstring之间的相互转换
  • 原文地址:https://www.cnblogs.com/bclshuai/p/14235574.html
Copyright © 2011-2022 走看看