您的位置:首页 > 编程语言 > C语言/C++

【WMI】WMI For C++/COM 获取系统信息过程

2007-08-22 21:30 369 查看
使用WMI获取系统信息过程
我们以获取本机系统为例,获取系统信息的过程如下:
1)初始化COM库
由于用C++编写WMI应用是基于COM技术的,所以必须初始化COM库,这时调用函数CoInitializeEx用于初始化COM库。


HRESULT hres;


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.


}


2)初始化COM库安全级别
调用函数CoInitializeSecurity用于初始化COM安全级别。


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.


}


3)连接到WMI命名空间
通过调用CoCreateInstance初始化WMI的定位器(IWbemLocator类型的实例)。


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.


}


4)创建WMI服务
调用IWbemLocator::ConnectServer方法,通过这个定位器连接到WMI的命名空间,通过把一个IWbemServices的实例以参数形式传递给ConnectServer方法,就会创建这个服务。如我们需要一些BIOS信息,那么需要使用的WMI提供程序是Win32_BIOS,则需要连接到ROOT//CIMV2命名空间中。


IWbemServices *pSvc = NULL;


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 (e.g. 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.


}



5)设置WMI服务的安全级别
根据上一步得到的服务,设置相应的服务安全级别。通常来说,如果我们没有设置适当的安全属性,COM安全方案不允许一个进程去访问另一个进程,因此如果我们要访问一个外部进程的对象,那么我们应该设置适当的IWbemServices的安全级别。


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.


}

6)使用WMI服务
使用之前得到的服务,可以进行一些操作,如查询、调用方法和其他一些操作。之后详细介绍
7)释放资源,关闭服务与连接,关闭COM库
在用完资源后,释放资源,关闭连接,关闭COM库等一些善后操作。


//可能在第六步还申请了其他资源,也要释放掉


pSvc->Release();


pLoc->Release();


pEnumerator->Release();


pclsObj->Release();


CoUninitialize();

如何使用WMI服务
前五步是申请服务,那么如何使用WMI提供的服务呢?
像优化大师或超级兔子那样,主要的操作是查询!即从Windows提供的WMI Provider中查询到我们想要的信息,比如多种多样的硬件/软件信息;有的时候,信息是动态的,或者某种元素的状态是可设置的,那就用到了调用方法;再或者,我们可以自己做一个提供程序,收集我们关心的信息,然后提供给用户......
WMI允许我们做的操作很多,查询同样信息的方法和途径也很多,包括同步、异步、半同步等。以后的几篇文章,我将blog下使用WMI服务的几种常用方式。也许,在学会了这种那种技术后,我们也能写出像优化大师或超级兔子一样的优秀软件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: