使用c++创建WMI应用程序
使用 C++为 WMI创建应用程序:您必须初始化COM、访问和设置 WMI协议,并进行手动清理。但是,C++具有灵活性和功能的优势。因此,虽然对于简单的过程,使用 VisualBasicScriptingEdition(VBScript)或Windows PowerShell效果更好,但对于更复杂的应用程序,C++效果更好,并且需要编写提供程序。
下面的过程描述如何创建WMI应用程序
1.初始化COM。
由于 WMI基于 COM 技术,因此必须执行对 ColnitializeEx 和ColnitializeSecurity 函数的调用才能访问 WMI。
连接到WMI的第一步是设置对 ColnitializeEx和 ColnitializeSecurity的COM调用
本主题中的代码示例需要以下引用和#include语句才能正确编译。
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
下面的过程描述如何从客户端应用程序初始化COM。
从客户端应用程序初始化COM
1.通过调用ColnitializeEx来初始化COM。
调用ColnitializeEx是设置COM接口的标准程序。因此,当调用Colnitialize Ex时,WMI不要求您遵守任何其他程序。
下面的代码示例描述如何调用 ColnitializeEx。
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr))
{ cout << "Failed to initialize COM library. Error code = 0x"
<< hex << hr << endl;
return hr;
}
2.通过调用 ColinitializeSecurity接口来设置一般的COM安全级别。
当为一个进程设置COM 接口时,您必须调用ColinitializeSecurity函数。如果要为整个进程设置或更改身份验证、模拟或身份验证服务的默认安全设置,请调用ColinitializeSecurity。。如果要设置或更改特定代理的安全,则必须调用 CoSetProxyBlanket。当在另一个进程内运行且无法控制身份验证、模拟或验证服务的默认安全设置时,必须调用CoSetProxy Blanket 来设置或更改COM安全。
下面的代码示例描述如何调用 ColinitializeSecurity来设置进程上的COM安全性。
hr = CoInitializeSecurity(
NULL, // Security descriptor
-1, // COM negotiates authentication service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
NULL, // Authentication info
EOAC_NONE, // Additional capabilities of the client or server
NULL); // Reserved
if (FAILED(hr))
{
cout << "Failed to initialize security. Error code = 0x"
<< hex << hr << endl;
CoUninitialize();
return hr; // Program has failed.
}
初始化COM后,下一步是创建与WMI命名空间的连接。
2.创建与WMI命名空间的连接。
根据定义,WMI运行在与您的应用程序不同的进程中。因此,您必须在您的应用程序与WMI之间建立连接。
在设置 COM 标准调用后,您必须通过调用IWbemLocator::ConnectServer方法连接到WMl。ConnectServer方法返回IWbemServices接口的代理。通过IWbemServices,您可以访问WMI的不同功能。
本主题中的代码示例需要以下引用和#include语句才能正确编译。
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <windows.h>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
下面的过程描述如何创建与WMI命名空间的连接。
创建与WMI命名空间的连接
通过调用CoCreatelnstance来初始化IWBEMLocator接口。
WMI不要求您在 [WbemLocator 上调用 CoCreatelnstance 时执行任何其他过程。
下面的代码示例描述了如何初始化lWbemLocator。
IWbemLocator *pLoc = 0;
HRESULT hr;
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hr))
{
cout << "Failed to create IWbemLocator object. Err code = 0x"
<< hex << hr << endl;
CoUninitialize();
return hr; // Program has failed.
}
通过调用 lWbemLocator::ConnectServer方法连接到WMI
ConnectServer方法将向IWBEM Services接口返回代理该接口用于访问在对 ConnectServer的调用中指定的本地或远程WMI命名空间。
下面的代码示例描述如何调用 ConnectServer。
IWbemServices *pSvc = 0;
// Connect to the root\default namespace with the current user.
hr = pLoc->ConnectServer(
BSTR(L"ROOT\\DEFAULT"), //namespace
NULL, // User name
NULL, // User password
0, // Locale
NULL, // Security flags
0, // Authority
0, // Context object
&pSvc); // IWbemServices proxy
if (FAILED(hr))
{
cout << "Could not connect. Error code = 0x"
<< hex << hr << endl;
pLoc->Release();
CoUninitialize();
return hr; // Program has failed.
}
cout << "Connected to WMI" << endl;
在收到指向IWBEM Services代理的指针后,必须设置该代理上的安全性才能访问WMI。
3.设置WMI连接的安全级别。
要使用创建到WMI的连接,必须为应用程序设置模拟和身份验证级别。
在检索到指向 IWbemServices 代理的指针后,必须设置代理的安全级别,以便通过代理访问 WMI。必须设置安全级别,因为IWbemServices中的代理会授予对进程外对象的访问权限。通常,如果不设置适当的安全属性,COM 安全不允许一个进程访问另一个进程。有关详细信息,请参设置 lWbemServices和其他代理的安全级别。连接到不同的操作系统需要不同程度的身份验证和冒名顶替。
本主题中的代码示例需要以下引用和#include语句才能正确编译。
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
下面的过程描述如何设置WMI连接上的安全级别。
要设置WMI连接的安全级别。通过调用CoSetProxyBlanket来设置IWBEMServices代理上的安全级别。
下面的代码示例描述了调用 CoSetProxyBlanket的常见方法。
HRESULT hres;
IWbemServices *pSvc = 0;
IWbemLocator *pLoc = 0;
// Set the proxy so that impersonation of the client occurs.
hres = CoSetProxyBlanket(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))
{
cout << "Could not set proxy blanket. Error code = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return hres; // Program has failed.
}
设置 lWbemServices 指针的安全级别后,您可以访问WMI的各种功能。使用完WMI后,必须关闭应用程序。
4.实现您的应用程序的目的。
WMI提供了各种 COM 接口,用于访问和操作您整个企业的数据。有关详细信息,请参阅操作类和实例信息、接收WMI事件和 COM APIfor WMl.
这是您的WMI客户机应用程序的大部分应该存在的地方,例如访问WMI对象或操作数据。
5.清理并关闭您的应用程序。
完成对WMI的查询后,应销毁所有COM指针并正确关闭应用程序。
在为IWBEM Services指针设置安全级别后,您可以访问WMI的名种功能。在使用完WMI后,必须关闭应用程序。
下面的过程描述了如何清理和关闭WMI应用程序。
要清理和关闭WMI应用程序
1.释放所有开放的COM接口。
您必须记住释放的两个主要接口是IWbemServices和lWbemLocator.
2.调用CoUninitialize。
与所有COM应用程序一样,您必须在应用程序的末尾调用CoUninitialize 。
3.退出您的申请。
下面的代码示例演示如何退出WMI客户端应用程序。
// The following #include and #define statements need
// to be used with this code:
// #define _WIN32_DCOM
// #include <wbemidl.h>
// #pragma comment(lib, "wbemuuid.lib")
// pSvc was declared as IWbemServices *pSvc;
// pLoc was declared as IWbemLocator *pLoc;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 0; // Program successfully completed.
您现在已成功初始化COM、访问WMI并退出应用程序。有关详细信息,请参阅示例:创建WMI应用程序