当前位置: 首页 > article >正文

使用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应用程序


http://www.kler.cn/a/294012.html

相关文章:

  • LLMs之Code:Github Spark的简介、安装和使用方法、案例应用之详细攻略
  • 外星人入侵
  • #渗透测试#SRC漏洞挖掘#云技术基础02之容器与云
  • 从 MySQL 5.7 到 8.0:理解 GROUP BY 的新规则与实战优化20241112
  • PHP API如何使用access_token开放接口有效期
  • Python 小高考篇(2)字符串
  • Llama 3.1大模型的预训练和后训练范式解析
  • 【如何有效率地阅读源码】
  • 搜维尔科技:蹦床、跳绳或骑马,OptiTrack可以捕捉难以想象的物体
  • Tensorflow2 如何扩展现有数据集(缩放、随机旋转、水平翻转、平移等),从而提高模型的准确率 -- Tensorflow自学笔记14
  • vscode安装使用plantuml插件
  • 从监控到智能:EasyCVR视频汇聚平台助力加油站安全监管升级转型
  • 网络安全服务基础Windows--第13节-加密技术
  • git的简单学习
  • 苹果系统(MacOS)资源管理器和终端的来回切换
  • ICM20948 DMP代码详解(5)
  • Vue eslint 语法检测问题
  • 水晶连连看 - 无限版软件操作说明书
  • 硬件工程师笔试面试知识器件篇——电感
  • [第三篇 运维与安全管理] ==> 第8章 数据库安全管理与审计
  • SpringCloud开发实战(三):集成Eureka注册中心
  • 算法训练营——day3长度最小子数组
  • 18055 主对角线上的元素之和
  • 超详细!!!electron-vite-vue开发桌面应用之应用更新版本提示(十三)
  • 数据集火焰检测 >> DataBall
  • 搭贝低代码平台在零售管理中的应用:推动企业快速数据化转型