WMI技术介绍和应用——VC开发WMI应用的基本步骤
在《WMI技术介绍和应用——WMI概述》中介绍了我们可以使用C++、.net或者支持ActiveX技术的脚本语言来使用WMI。但是各种语言对WMI的控制能力是不同的,比如脚本语言只能用来从WMI获取数据或者接收事件通知。而C++还可以编写WMI提供者和发送消息。和脚本语言相比,C++对WMI有强大的控制和定制性,当然也具有更大的复杂性。本文将主要讲述使用VC如何搭建一个使用WMI的框架。(转载请指明出于breaksoftware的csdn博客)
为了方便使用,我将该搭建步骤封转到了一个类中
class CWMI
{
public:CWMI();~CWMI(void);
public:HRESULT ExcuteFun();
protected:VOID SetNamespace(wstring wstrNamespace);
private:HRESULT InitialCom();HRESULT SetComSecLevels();HRESULT ObtainLocator2WMI(CComPtr<IWbemLocator>& pLoc);HRESULT Connect2WMI(CComPtr<IWbemLocator> pLoc,CComPtr<IWbemServices>& pSvc);HRESULT SetProxySecLevels(CComPtr<IWbemServices> pSvc);virtual HRESULT Excute(CComPtr<IWbemServices> pSvc) = 0;
private:wstring m_wstrNamespace;
};
SetNamespace用于设置命名空间。在《WMI技术介绍和应用——WMI概述》中我们提到,WMI中存在诸如root\default、root\cimv2等WMI命令空间。因为我们要使用的WMI功能和命名空间有很大的关联,所以该类将提供这个设置命令空间的函数。
VOID CWMI::SetNamespace(wstring wstrNamespace)
{m_wstrNamespace = wstrNamespace;
}
剩下的函数就承载着了使用WMI步骤的逻辑和流程。
初始化COM库
我们还要将之前的WMI框架图列出来
WMI是基于COM技术的。在WMI Consumers层,我们发现,C++程序是直接和WMI COM API进行交互。所以我们要先初始化COM组件库。
HRESULT CWMI::InitialCom()
{HRESULT hr = E_FAIL;do {hr = CoInitializeEx(0, COINIT_MULTITHREADED);CHECKHR(hr);} while (0);return hr;
}
设置进程COM安全信息
因为WMI是基于COM技术的,所以我们可以使用CoInitializeSecurity设置我们应用的认证信息和扮演等级(Impersonation Levels)。如果我们不调用该函数,COM将通过读取注册表中的相关键值去决定我们应用的认证信息和扮演等级。然而,往往注册表中记录的认证信息和扮演等级是非常低的。一般来说,注册表记录的扮演等级是RPC_C_IMP_LEVEL_IDENTIFY,而绝大部分WMI提供者至少需要RPC_C_IMP_LEVEL_IMPERSONATE等级。对于认证信息,在特殊场景下,我们可能需要用其他用户身份去使用COM。但是目前,我在管理员权限下运行程序,权限基本上是够得,所以设置也很简单。
HRESULT CWMI::SetComSecLevels()
{// Set general COM security levels --------------------------// Note: If you are using Windows 2000, you must specify -// the default authentication credentials for a user by using// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----// parameter of CoInitializeSecurity ------------------------HRESULT hr = E_FAIL;do {hr = CoInitializeSecurity(NULL, -1, // COM negotiates serviceNULL, // Authentication servicesNULL, // ReservedRPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation NULL, // Authentication infoEOAC_NONE, // Additional capabilities NULL // Reserved);CHECKHR(hr);} while (0);return hr;
}
创建进程内COM服务器
我们应用中使用WMI完成相关功能,比如查询硬盘ID,实际执行查询的操作是在WMI服务中执行的,而不是我们的应用。比如,在XP上,svchost.exe服务是WMI服务的载体。我们应用通过COM告诉svchost.exe我们的请求,svchost.exe将我们请求执行后,会将结果通过COM传递给我们的应用。这样就要求我们应用和WMI服务进程有通信。在我们应用这边,就需要创建一个进程内COM服务器用于接发数据。
HRESULT CWMI::ObtainLocator2WMI(CComPtr<IWbemLocator>& pLoc)
{HRESULT hr = E_FAIL;do {hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);CHECKHR(hr);} while (0);return hr;
}
连接WMI命名空间
这步是使用WMI的关键一步。我们使用上一步创建的IWbemLocator实例的ConnectServer函数连接本地或者远程的WMI命名空间。我们看一下函数声明
HRESULT ConnectServer([in] const BSTR strNetworkResource,[in] const BSTR strUser,[in] const BSTR strPassword,[in] const BSTR strLocale,[in] LONG lSecurityFlags,[in] const BSTR strAuthority,[in] IWbemContext *pCtx,[out] IWbemServices **ppNamespace
);
第一个参数strNetworkResource是命名空间的名字,比如"root\default"或者"\\.\root\default"。第二三个是用户名和密码,如果是远程计算机,则这两个参数非常有用。最后一个参数返回了IWbemServices结构的代理。我们可以通过该代理访问WMI服务。
HRESULT CWMI::Connect2WMI( CComPtr<IWbemLocator> pLoc,CComPtr<IWbemServices>& pSvc )
{HRESULT hr = E_FAIL;do {hr = pLoc->ConnectServer(CComBSTR(m_wstrNamespace.c_str()), NULL, NULL, NULL, NULL, NULL, NULL, &pSvc );CHECKHR(hr);} while (0);return hr;
}
设置WMI连接的安全等级
一般来说,如果没有设置正确的安全属性,COM是不允许一个进程去访问另一个进程的中的对象。我们上步获得的IWbemServices接口代理就需要访问WMI服务进程中的对象,所以我们要对该代理设置安全等级。
HRESULT CWMI::SetProxySecLevels( CComPtr<IWbemServices> pSvc )
{HRESULT hr = E_FAIL;do {hr = CoSetProxyBlanket(pSvc, // Indicates the proxy to setRPC_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_xxxNULL, // client identityEOAC_NONE // proxy capabilities );CHECKHR(hr);} while (0);return hr;
}
发起WMI请求
通过以上一系列过程,我们终于可以开始使用WMI了。在我定义的类中,我将该步骤封装成一个纯虚函数Excute,继承CWMI的类将实现具体的工作。
清理
我们在使用完以上的代理和实例后,我们要释放它们,并且最后要释放COM库。
CWMI::~CWMI(void)
{CoUninitialize();
}
总体来说执行的流程用代码可以描述为
HRESULT CWMI::ExcuteFun()
{HRESULT hr = E_FAIL;CComPtr<IWbemLocator> pLoc = NULL;CComPtr<IWbemServices> pSvc = NULL;do {hr = InitialCom();CHECKHR(hr);hr = SetComSecLevels();CHECKHR(hr);hr = ObtainLocator2WMI(pLoc);CHECKHR(hr);hr = Connect2WMI(pLoc, pSvc);CHECKHR(hr);hr = SetProxySecLevels(pSvc);CHECKHR(hr);hr = Excute(pSvc);CHECKHR(hr);} while (0);return hr;
}
下一节,我将讲解一个简单的对CWMI的封装类。
工程源码见《WMI技术介绍和应用——WMI概述》结尾。
相关文章:

WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类
在《WMI技术介绍和应用——VC开发WMI应用的基本步骤》文中,我们介绍了VC使用WMI技术的基本框架。本节我将讲解封装和实现一个用于半同步查询WMI的类。(转载请指明出于breaksoftware的csdn博客) 我曾思考过如何编写一个比较有用的类࿰…

致被套基民:老基民的四点教训七点经验(ZT)
四点错误: 一是没有足够的耐心。比如我曾买入一只基金,上半年表现不好,在忍无可忍之下终于赎回,结果它在下半年股市调整时大放异彩,成为收益率的冠军; 二是只看高分红买基金,结果错过了几只净值…
千万用户同时在线,优酷智能档在双11“猫晚”直播如何防卡顿?
作者 | 阿里文娱高级技术专家肖文良出品 | AI科技大本营(ID:rgznai100) 导读:本文为阿里文娱高级技术专家肖文良在【阿里文娱2019双11猫晚技术沙龙】中的演讲,主要内容为如何通过优酷智能档,降低用户卡顿尤其是双11直播…

导航菜单:jQuery粘性滚动导航栏效果
粘性滚动是当导航在滚动过程中会占粘于浏览器上,达到方便网站页面浏览的效果,也是一种用户体验,下面我们看一下是怎么实现的: jQuery的 smint插件,也是一个导航菜单固定插件。当页滚动时,导航菜单会固定在顶…
如何用Python实现超级玛丽的人物行走和碰撞检测?
作者 | marble_xu编辑 | 郭芮出品 | CSDN博客在《如何用 Python 实现超级玛丽的界面和状态机?》这篇文章中我们讲解如何用代码实现界面和状态机,本文详解人物行走和碰撞检测的实现。功能介绍人物行走人物的行走速度这边分成水平方向(X轴&…

WMI技术介绍和应用——查询正在运行的进程信息
在《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》一文中,我们介绍到了一个半同步查询WMI类的框架。本文将是该技术的一个应用,介绍如何使用WMI技术查询正在运行的进程信息。(转载请指明出于breaksoftware的csdn博客ÿ…

20个经典要诀学好英语
出处:我学网互助论坛第一要诀:收听英语气象报告 有些教学录音带为配合初学者的学习,故意放慢语速,这对英语听力的训练是不够的。如果听语速正常的英语,初学者又会感到力不从心。英语气象报告的速度虽快,…

ArduinoYun教程之通过网络为Arduino Yun编程
ArduinoYun教程之通过网络为Arduino Yun编程 Arduino Yun的软件部分 通过第一章的介绍后读者就明白了Arduino Yun除了是一个类似其他Arduino的单片机之外,它的另一大组成部分就是运行着一个特殊Linux发行版的Atheros AR9331芯片。所以,本章将会介绍Ather…

WMI技术介绍和应用——查询正在运行的线程信息
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。 一般来说,如果试图枚举系统中的线程。需要先枚举系统中的进程,然后再枚举每个进程中的线程。而WMI给我们提供了一种比较简便的枚举线程信息的方法。࿰…
开源生态也难逃“卡脖子”危机?中国AI开发者的警醒和突围
开源不是一个新名词,也不是一个新行动。软件时代,开源推动了全球范围的创新技术成果落地,从而促进全球信息技术发生了全局性、持续性的重大变革,这使它甚至成为一条非常关键且成功的技术路线。随着AI时代的来临,阿里、…

Linux下应用软件的安装
对于刚刚接触Linux的朋友来说,安装一些应用软件是一件头疼的事,因为在Linux下安装应用软件和Windows下截然不同的,下面介绍一下Linux下安装应用软件来解决刚刚接触Linux而不会安装软件朋友的困惑.Linux下软件包有两种比较常见的形式,一种是以 RPM、deb包为代表的智能…

Hibernate 的 session.load()使用方法
2019独角兽企业重金招聘Python工程师标准>>> protected Person getOne(int id){ Session session HibernateSessionFactory.getSession(); Person person new Person(); try{ session.load(person, id); }catch(Exception e){ e.printStackTrace(); }final…

WMI技术介绍和应用——查询桌面信息
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。 在Windows操作系统中,存在很多Windows Station。而每一个Windows Station又存在一个或者多个Windows Desktop。我们一般所说的桌面只是这些众多桌面中的一个。以下内容将介…
联泰集群发布水晶系列工作站,用于深度学习场景
北京时间2019年12月26日,联泰集群在北京正式发布了水晶系列工作站产品 W722、W7224和W5232。 联泰集群硬件产品技术中心总监刘振锋、软件产品技术中心总监孙建军、硬件产品技术中心工程师肖学文分别从应用方向、水晶工作站一体化软件平台及水晶系列产品硬件方面对本…

航空黑客私人YY
坐飞机从从云南飞回老家广州~~~当然绝对支持深圳航空啦!嘎嘎!为啥?当然是服务好 MM太PL了!呵呵!而且在看杂志的同时还看到了一则新闻 内容如下 近日,深圳航空公司与瑞士OnAir公司在香港签约,合作推动在飞机上实现万米高空的自由通信。2008年奥运会前&am…

Redis安装整理(window平台) +php扩展redis
window平台Redis安装 redis windows安装文件下载地址:http://code.google.com/p/servicestack/wiki/RedisWindowsDownload#Download_32bit_Cygwin_builds_for_Windows我选择的redis为最新版的安装文件,见下图: Redis安装文件解压后,有以下…

WMI技术介绍和应用——查询环境变量
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。 我们可以通过系统属性查看当前系统和当前用户的环境变量。(转载请指明出于breaksoftware的csdn博客) 如何使用WMI枚举所有环境变量的信息? CSynQue…
想学新的编程语言?考虑下Go吧
作者 | Lewis Fairweather译者 | 弯月,责编 | Elle来源 | CSDN(ID:CSDNnews)【导读】快速的运行时、高效的并发、简单易学的语法,这些都是Go语言最吸引人的特性。以下为译文:Go语言的入门门槛之低令我感到惊…

oracle学习总结三(bulk collect用法)
通过bulk collect减少loop处理的开销发表人:logzgh | 发表时间: 2006年五月19日, 10:56采用bulk collect可以将查询结果一次性地加载到collections中。而不是通过cursor一条一条地处理。可以在select into,fetch into,returning into语句使用bulk collect。注意在使用bulk coll…

MQTT的学习研究(五) MQTT moquette 的 Blocking API 发布消息服务端使用
参看官方文档: http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/index.jsp?topic/com.ibm.mq.amqtat.doc/tt00000_.htm * Java 为 MQ Telemetry Transport 创建异步发布程序 *在此任务中,您将遵循教程来修改第一个发布程序。通过修改,…

WMI技术介绍和应用——查询驱动信息
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。 如何使用WMI查询所有驱动信息?(转载请指明出于breaksoftware的csdn博客) CSynQueryData recvnotify(L"root\\CIMV2",L"SELECT * FR…

NumericUpDown
NumericUpDown控件主要功能是为一个TextBox控件添加上下按钮,当单击按钮时实现数字的加减,同时也可以提供静态数据,实现这些数据的上下选择。 属性列表: TargetControlID:该控件的目标作用控件。 Width&…
提高建模效率,改变手工作坊式生产,AutoML的技术研究与应用进展如何了?
整理 | 王银出品 | AI科技大本营(ID:rgznai100)【导读】12 月 5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑协办的中国大数据技术大会(BDTC 2019)在北京长城饭店隆重举…

.net使用memcached
Windows中memached安装 -------------服务器端配置 1>开始>运行:CMD(确定) 2>cd C:\memcached(回车) 3>memcached -d install(回车 这步执行安装) 4>memcached -d start(回车 这步执行启动memcache服务器,默认分配64M内存&…
22张精炼图笔记,深度学习专项学习必备
作者 | DL&CV_study9编辑 | Elle来源 | CSDN 博客本文为人工智能学习笔记记录。【深度学习基础篇】一、深度学习基本概念监督学习:所有输入数据都有确定的对应输出数据,在各种网络架构中,输入数据和输出数据的节点层都位于网络的两端&…

WMI技术介绍和应用——查询文件夹信息
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句,具体使用参看前面的例子。 本节主要介绍Win32_Directory类。通过该类我们将可以获得部分常用的文件夹信息。在该类中,有属性Name&#x…

CSLA .NET概述
CSLA是Component-based, Scalable, Logical Architecture的简写,CSLA .NET是Rockford Lhotka基于.Net设计的一套N-tier分布式框架。 CSLA .NET包含如下功能: l n-Level undo capability 译:n层撤销功能 l Tracking broke…

简短的几句js实现css压缩和反压缩功能
写在前面 最近一直在整理css,但因为现在Visual Studio 2013太智能了,它每每在我按ctrlED进行格式化代码的时候,就会将css进行层次格式化(如下图所示),而这个格式让我老大实在无法忍受,我老大认为…
迁移学习前沿研究亟需新鲜血液,深度学习理论不能掉链子
作者 | Frederico Guth,Tefilo Emidio de Campos编译 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】人类可以从很少的样本中学习,显示出了人类卓越的泛化能力,而这一点学习算法仍远做不到。当前,最成功的模型需要大量标记好的…

WMI技术介绍和应用——查询磁盘分区和逻辑磁盘信息
本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句,具体使用参看前面的例子。(转载请指明出于breaksoftware的csdn博客) 本节主要介绍Win32_DiskPartition和Win32_LogicalDisk两…