博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用C++进行WMI查询的简单封装
阅读量:5163 次
发布时间:2019-06-13

本文共 10381 字,大约阅读时间需要 34 分钟。

封装WMI查询的简单类CWMIUtil

头文件WMIUtil.h

#pragma once#include 
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 
# 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]\r\n"), dwPID, dwErrorCode);                }                else                {                    // 299错误,是因为32位进程尝试获取64位进程的路径而导致的,这正是下面继续用WMI的理由,因此不处理这个错误                }            }            CloseHandle(hProcess);        }        else        {            ErrorLog(TEXT("OpenProcess [PID = %lu] fail, error code is [%lu]\r\n"), dwPID, GetLastError());        }         // 若失败,再用WMI获取        if (bReturn)        {            break;        }         CWMIUtil wmi;         if (!wmi.Init())        {            ErrorLog(TEXT("wmi init fail, error code is [%lu], error msg is [%s]\r\n"), wmi.GetErrorCode(), wmi.GetErrorInfo());            break;        }         if (!wmi.ConnectServer())        {            ErrorLog(TEXT("wmi connect server fail, error code is [%lu], error msg is [%s]\r\n"), 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]\r\n"), wmi.GetErrorCode(), wmi.GetErrorInfo());            break;        }         if (!wmi.Next())        {            ErrorLog(TEXT("wmi next fail, error code is [%lu], error msg is [%s]\r\n"), 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]\r\n"), wmi.GetErrorCode(), wmi.GetErrorInfo());            break;        }         bReturn = TRUE;     } while (FALSE);     return bReturn;}

转载于:https://www.cnblogs.com/hjbf/p/10775062.html

你可能感兴趣的文章
Html - Table 表头固定和 tbody 设置 height 在IE不起作用的解决
查看>>
20165205 学习基础与C语言基础调查
查看>>
iOS SVN终端指令
查看>>
SpringSecurity——默认过滤器链
查看>>
LeetCode: Word Ladder II [127]
查看>>
Linux如何更新软件源
查看>>
SQL使用CASE 语句
查看>>
day8 (异常处理和网络编程)
查看>>
php中函数 vsprintf() 和 var_export()
查看>>
github 入门教程之 github 访问速度太慢怎么办
查看>>
多线程(1)—单线程
查看>>
HTML5权威指南 16.拖放API与通知API
查看>>
NYOJ-289 苹果 又是一个典型的01背包和上题一样没啥好说的
查看>>
HDU 2262 回溯算法 递归枚举
查看>>
九度0J 1374 所有员工年龄排序
查看>>
查询某端口的连接数
查看>>
listview初始化后仍为空
查看>>
无刷新分页
查看>>
SIFT算法
查看>>
git各种撤销操作
查看>>