zoukankan      html  css  js  c++  java
  • 使用C++进行WMI查询的简单封装

    封装WMI查询的简单类CWMIUtil

    头文件WMIUtil.h

    #pragma once
    #include <Wbemidl.h>
     
    class CWMIUtil
    {
    public:
        CWMIUtil(void);
        virtual ~CWMIUtil(void);
     
    private:
        // 禁止复制和赋值
        CWMIUtil(const CWMIUtil&);
        CWMIUtil& operator = (const CWMIUtil&);
     
    public:
        DWORD GetErrorCode() const;
        const TCHAR *GetErrorInfo() const;
    private:
        void SetErrorCode(const DWORD dwErrorCode);
        void SetErrorInfo(const TCHAR *szFormat, ...);
     
    public:
        BOOL Init();
        BOOL ConnectServer(const TCHAR *szServer = TEXT("ROOT\CIMV2"));
        BOOL ExecQuery(const TCHAR *szQuerySql);
        BOOL Next();
        BOOL GetProperty(const TCHAR *szValueName, TCHAR *szValue, const DWORD dwSizeInByte);
     
    private:
        DWORD m_dwErrorCode;
        CString m_csErrorInfo;
     
    private:
        BOOL m_bInitComSuccess;
     
    private:
        IWbemLocator *m_pLoc;
        IWbemServices *m_pSvc;
        IEnumWbemClassObject* m_pEnumerator;
        IWbemClassObject *m_pCurObj;
    };
    源文件WMIUtil.cpp
    #include "stdafx.h"
    #include "WMIUtil.h"
     
    #define _WIN32_DCOM
    #include <comdef.h>
    # pragma comment(lib, "wbemuuid.lib")
     
    CWMIUtil::CWMIUtil(void)
        : m_dwErrorCode(0), m_csErrorInfo(TEXT("")), m_bInitComSuccess(FALSE)
        , m_pLoc(NULL), m_pSvc(NULL), m_pEnumerator(NULL), m_pCurObj(NULL)
    {
    }
     
    CWMIUtil::~CWMIUtil(void)
    {
        try
        {
            // 释放对象
            if (m_pCurObj)
            {
                m_pCurObj->Release();
            }
            if (m_pEnumerator)
            {
                m_pEnumerator->Release();
            }
            if (m_pSvc)
            {
                m_pSvc->Release();
            }
            if (m_pLoc)
            {
                m_pLoc->Release();
            }
            if (m_bInitComSuccess)
            {
                CoUninitialize();
            }
        }
        catch (_com_error &e)
        {
            // COM exception
        }
        catch (CException &e)
        {
            // MFC exception
        }
        catch (...)
        {
            // all exception
        }
    }
     
    DWORD CWMIUtil::GetErrorCode() const
    {
        return m_dwErrorCode;
    }
     
    const TCHAR *CWMIUtil::GetErrorInfo() const
    {
        return m_csErrorInfo.GetString();
    }
     
    void CWMIUtil::SetErrorCode(const DWORD dwErrorCode)
    {
        m_dwErrorCode = dwErrorCode;
    }
     
    void CWMIUtil::SetErrorInfo(const TCHAR *szFormat, ...)
    {
        int nSize = 1024;
        TCHAR *szBuf = new TCHAR[nSize];
        ZeroMemory(szBuf, nSize * sizeof(TCHAR));
     
        try
        {
            va_list args;
            va_start(args, szFormat);
            nSize = _vsntprintf_s(szBuf, nSize, _TRUNCATE, szFormat, args);
            if (nSize < 0)
            {
                m_csErrorInfo = TEXT("SetErrorInfo error, _vsntprintf_s return size less than 0");
            }
            else
            {
                m_csErrorInfo = szBuf;
            }
        }
        catch (...)
        {
            m_csErrorInfo = TEXT("SetErrorInfo error, _vsntprintf_s exception");
        }
     
        delete [] szBuf;
    }
     
    BOOL CWMIUtil::Init()
    {
        BOOL bReturn = FALSE;
     
        do 
        {
            // 初始化COM接口
            HRESULT hres =  CoInitializeEx(0, COINIT_APARTMENTTHREADED); 
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Failed to initialize COM library. Error code = 0x%x"), hres);
                break;
            }
     
            hres =  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT
                , RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
     
            if (FAILED(hres) && RPC_E_TOO_LATE != hres)
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Failed to initialize security. Error code = 0x%x"), hres);
                break;
            }
     
            m_bInitComSuccess = TRUE;
            bReturn = TRUE;
     
        } while (FALSE);
     
        return bReturn;
    }
     
    BOOL  CWMIUtil::ConnectServer(const TCHAR *szServer /* = TEXT("ROOT\CIMV2") */)
    {
        // 有效性判断
        if (!m_bInitComSuccess)
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("Init COM failed, can not connect server"));
            return FALSE;
        }
     
        BOOL bReturn = FALSE;
     
        do 
        {
            // 连接服务器
            HRESULT hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&m_pLoc);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Failed to create IWbemLocator object. Error code = 0x%x"), hres);
                break;
            }
     
            hres = m_pLoc->ConnectServer(_bstr_t(CStringW(CString(szServer))), NULL, NULL, 0, NULL, 0, 0, &m_pSvc);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Could not connect to server [%s]. Error code = 0x%x"), szServer, hres);
                break;
            }
     
            hres = CoSetProxyBlanket(m_pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL
                , RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Could not set proxy blanket. Error code = 0x%x"), hres);
                break;
            }
     
            bReturn = TRUE;
     
        } while (FALSE);
     
        return bReturn;
    }
     
    BOOL CWMIUtil::ExecQuery(const TCHAR *szQuerySql)
    {
        // 有效性判断
        if ((NULL == m_pLoc) || (NULL == m_pSvc))
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("Do not connent to any server yet, can not exec query"));
            return FALSE;
        }
     
        if (CString(szQuerySql).IsEmpty())
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("QuerySql is empty, can not exec"));
            return FALSE;
        }
     
        BOOL bReturn = FALSE;
     
        do 
        {
            // 执行WMI查询语句
            HRESULT hres = m_pSvc->ExecQuery(_bstr_t(L"WQL"), _bstr_t(CStringW(CString(szQuerySql))), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY
                , NULL, &m_pEnumerator);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("ExecQuery [%s] failed. Error code = 0x%x"), szQuerySql, hres);
                break;
            }
     
            bReturn = TRUE;
     
        } while (FALSE);
     
        return bReturn;
    }
     
    BOOL CWMIUtil::Next()
    {
        // 有效性判断
        if (NULL == m_pEnumerator)
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("Do not exec any query yet, can not call next"));
            return FALSE;
        }
     
        BOOL bReturn = FALSE;
        
        do 
        {
            // 枚举下一个类对象
            ULONG uReturn = 0;
     
            HRESULT hres = m_pEnumerator->Next(WBEM_INFINITE, 1, &m_pCurObj, &uReturn);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Enumerate next object failed. Error code = 0x%x"), hres);
                break;
            }
     
            bReturn = uReturn;
     
        } while (FALSE);
     
        return bReturn;
    }
     
    BOOL CWMIUtil::GetProperty( const TCHAR *szValueName, TCHAR *szValue, const DWORD dwSizeInByte )
    {
        // 有效性判断
        if (NULL == m_pCurObj)
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("No object, so no property"));
            return FALSE;
        }
     
        if (CString(szValueName).IsEmpty() || (NULL == szValue) || dwSizeInByte <= 0)
        {
            SetErrorCode(1);
            SetErrorInfo(TEXT("Params invalid: value name is empty or value buffer is null"));
            return FALSE;
        }
     
        BOOL bReturn = FALSE;
     
        do 
        {
            // 获取当前类对象的指定属性
            VARIANT vtPropPath;
            HRESULT hres = m_pCurObj->Get(CStringW(CString(szValueName)), 0, &vtPropPath, 0, 0);
     
            if (FAILED(hres))
            {
                SetErrorCode(hres);
                SetErrorInfo(TEXT("Get proterty [%s] value failed. Error code = 0x%x"), szValueName, hres);
                break;
            }
     
            CString csValue;
            switch(vtPropPath.vt)
            {
            case VT_BSTR:
                csValue = CString(CStringW(vtPropPath.bstrVal));
                break;
     
            default:
                break;
            }
            VariantClear(&vtPropPath);
     
            if (!csValue.IsEmpty())
            {
                memcpy_s(szValue, dwSizeInByte, csValue.GetString(), csValue.GetLength() * sizeof(TCHAR));
                bReturn = TRUE;
            }
     
        } while (FALSE);
     
        return bReturn;
    }

    注意:其中函数GetProperty只处理了vtPropPath.vt是VT_BSTR的情况。

    下面来个使用示例。

    我上一篇文章正好讲了获取进程路径的问题,那么就写一个获取进程路径的函数,其中dwPID是进程PID(输入参数),szFullPath是获取到的进程路径(输出参数):

    BOOL GetProcessFullNameByPID( const DWORD dwPID, TCHAR *szFullPath, const DWORD dwSizeInByte )
    {
        // 有效性判断
        if (0 == dwPID || NULL == szFullPath || dwSizeInByte < sizeof(TCHAR))
        {
            return FALSE;
        }
     
        BOOL bReturn = FALSE;
     
        do 
        {
            // 先用GetModuleFileNameEx获取
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID);
            if (NULL != hProcess)
            {
                if (GetModuleFileNameEx(hProcess, NULL, szFullPath, dwSizeInByte / sizeof(TCHAR)))
                {
                    if (!CString(szFullPath).IsEmpty())
                    {
                        bReturn = TRUE;
                    }
                }
                else
                {
                    const DWORD dwErrorCode = GetLastError();
                    if (299 != dwErrorCode)
                    {
                        ErrorLog(TEXT("GetModuleFileNameEx [PID = %lu] fail, error code is [%lu]
    "), dwPID, dwErrorCode);
                    }
                    else
                    {
                        // 299错误,是因为32位进程尝试获取64位进程的路径而导致的,这正是下面继续用WMI的理由,因此不处理这个错误
                    }
                }
                CloseHandle(hProcess);
            }
            else
            {
                ErrorLog(TEXT("OpenProcess [PID = %lu] fail, error code is [%lu]
    "), dwPID, GetLastError());
            }
     
            // 若失败,再用WMI获取
            if (bReturn)
            {
                break;
            }
     
            CWMIUtil wmi;
     
            if (!wmi.Init())
            {
                ErrorLog(TEXT("wmi init fail, error code is [%lu], error msg is [%s]
    "), wmi.GetErrorCode(), wmi.GetErrorInfo());
                break;
            }
     
            if (!wmi.ConnectServer())
            {
                ErrorLog(TEXT("wmi connect server fail, error code is [%lu], error msg is [%s]
    "), wmi.GetErrorCode(), wmi.GetErrorInfo());
                break;
            }
     
            CString csQuery;
            csQuery.Format(TEXT("SELECT * FROM Win32_Process WHERE ProcessId="%lu""), dwPID);
            if (!wmi.ExecQuery(csQuery))
            {
                ErrorLog(TEXT("wmi exec query fail, error code is [%lu], error msg is [%s]
    "), wmi.GetErrorCode(), wmi.GetErrorInfo());
                break;
            }
     
            if (!wmi.Next())
            {
                ErrorLog(TEXT("wmi next fail, error code is [%lu], error msg is [%s]
    "), wmi.GetErrorCode(), wmi.GetErrorInfo());
                break;
            }
     
            if (!wmi.GetProperty(TEXT("ExecutablePath"), szFullPath, dwSizeInByte))
            {
                ErrorLog(TEXT("wmi get property fail, error code is [%lu], error msg is [%s]
    "), wmi.GetErrorCode(), wmi.GetErrorInfo());
                break;
            }
     
            bReturn = TRUE;
     
        } while (FALSE);
     
        return bReturn;
    }

    https://blog.csdn.net/mkdym/article/details/8760975

  • 相关阅读:
    springmvc中@PathVariable和@RequestParam的区别
    Spring MVC 学习总结(一)——MVC概要与环境配置
    web中session与序列化的问题
    EL表达式
    JSTL自定义标签
    [c++][语言语法]stringstream iostream ifstream
    [C++][语言语法]标准C++中的string类的用法总结
    [数据库]数据库查询语句
    [c++][语言语法]函数模板和模板函数 及参数类型的运行时判断
    机器学习算法汇总
  • 原文地址:https://www.cnblogs.com/hjbf/p/10775062.html
Copyright © 2011-2022 走看看