使用C++进行WMI查询的简单封装
2013-04-05 12:33
441 查看
封装WMI查询的简单类CWMIUtil
头文件WMIUtil.h
源文件WMIUtil.cpp
注意:其中函数GetProperty只处理了vtPropPath.vt是VT_BSTR的情况。
下面来个使用示例。
我上一篇文章正好讲了获取进程路径的问题,那么就写一个获取进程路径的函数,其中dwPID是进程PID(输入参数),szFullPath是获取到的进程路径(输出参数):
头文件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]\r\n"), dwPID, dwErrorCode); } else { // 299错误,是因为32位进程尝试获取64位进程的路径而导致的,这正是下面继续用WMI的理由,因此不处理这个错误 } } CloseHandle(hProcess); } else { ErrorL 4000 og(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; }
相关文章推荐
- C++使用try&catch进行异常处理的简单范例
- 第十七天dbutils的使用------Commons DbUtils(Apache)第三方的:只是对JDBC编码进行了简单的封装
- 使用Retrofit和Rxjava对联网进行简单封装
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- C++使用sqlite3进行简单的课表管理
- 一个使用超简单C++封装的网络库(包含服务器端和客户端,跨平台,比较适用于移动终端)
- 对libpq进行简单的c++封装
- [C++]数据结构实验04:使用堆栈进行简单的四则运算
- 【Android】Retrofit的使用(3)-对Retrofit进行简单的封装
- 对libpq进行简单的c++封装
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- 使用JDBC对数据库进行查询的前期准备工作,以及简单的JDBC访问MySQL数据库(Mac)
- 1个比较简单的使用java反射机制获取前台数据进行数据封装的例子
- 使用闭包对setTimeout进行简单封装
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- Android Studio下使用JAVA+Appium进行自动化测试及简单封装
- GreenDao数据库框架 最精简使用教程 并对其进行简单封装
- windows下WMI使用C++查询用户硬件信息
- 使用闭包对setTimeout进行简单封装避免出错