WMI简介
- Windows Management Instrumentation(WMI)是Microsoft Windows操作系统中一个强大的管理框架,它允许管理员以及开发者以标准化的方式访问和控制系统的各种硬件、操作系统组件、应用程序以及网络资源。
- WMI是基于Web-Based Enterprise Management (WBEM)和Common Information Model (CIM)标准的实现,旨在为IT管理提供一个统一的、面向对象的接口。
- 本文章主要介绍了WMI技术以及如何使用WMI技术获取系统信息。并且提供了一种判断带参进程是否运行的方法。
WMI的工作原理
- WMI架构包含几个关键组件,如WMI服务、WMI提供程序(Providers)、WMI仓库(Repository)和客户端工具。客户端通过WMI接口发送请求,WMI服务负责解析请求并调用相应的提供程序来获取或修改数据,最后将结果返回给客户端。WMI仓库则存储了所有可用的WMI类和实例信息,形成了一个系统信息的中央数据库。
- 总之,WMI是一个功能强大、灵活且深入Windows系统内部的管理工具,它在系统管理、监控和自动化领域扮演着至关重要的角色。然而,由于其广泛的能力,确保WMI的安全配置也是维护系统安全的关键环节之一。
使用介绍
命令行使用
- 以下命令可在cmd命令行直接执行
帮助命令查看
- 命令
wmic /?
- 结果(第二大组表示了可以使用命令行访问和操作的WMI信息)
WMIC 已弃用。 [全局开关] <命令> 可以使用以下全局开关: /NAMESPACE 别名在其上操作的命名空间的路径。 /ROLE 包含别名定义的角色的路径。 /NODE 别名在其上操作的服务器。 /IMPLEVEL 客户端模拟级别。 /AUTHLEVEL 客户端身份验证级别。 /LOCALE 客户端应使用的语言 ID。 /PRIVILEGES 启用或禁用所有权限。 /TRACE 将调试信息输出到 stderr。 /RECORD 记录所有输入命令和输出内容。 /INTERACTIVE 设置或重置交互模式。 /FAILFAST 设置或重置 FailFast 模式。 /USER 会话期间要使用的用户。 /PASSWORD 登录会话时要使用的密码。 /OUTPUT 指定输出重定向模式。 /APPEND 指定输出重定向模式。 /AGGREGATE 设置或重置聚合模式。 /AUTHORITY 指定连接的 <授权类型>。 /?[:<BRIEF|FULL>] 用法信息。 有关特定全局开关的详细信息,请键入: switch-name /? 当前角色中可以使用以下别名: ALIAS - 对本地系统上可用别名的访问 BASEBOARD - 基板(也称为主板或系统板)管理。 BIOS - 基本输入/输出服务(BIOS)管理。 BOOTCONFIG - 启动配置管理。 CDROM - CD-ROM 管理。 COMPUTERSYSTEM - 计算机系统管理。 CPU - CPU 管理。 CSPRODUCT - SMBIOS 中的计算机系统产品信息。 DATAFILE - 数据文件管理。 DCOMAPP - DCOM 应用程序管理。 DESKTOP - 用户的桌面管理。 DESKTOPMONITOR - 桌面监视器管理。 DEVICEMEMORYADDRESS - 设备内存地址管理。 DISKDRIVE - 物理磁盘驱动器管理。 DISKQUOTA - 用于 NTFS 卷的磁盘空间使用量。 DMACHANNEL - 直接内存访问(DMA)通道管理。 ENVIRONMENT - 系统环境设置管理。 FSDIR - 文件系统目录项管理。 GROUP - 组帐户管理。 IDECONTROLLER - IDE 控制器管理。 IRQ - 中断请求线路(IRQ)管理。 JOB - 提供对使用计划服务安排的作业的访问。 LOADORDER - 定义执行依赖关系的系统服务的管理。 LOGICALDISK - 本地存储设备管理。 LOGON - 登录会话。 MEMCACHE - 缓存内存管理。 MEMORYCHIP - 内存芯片信息。 MEMPHYSICAL - 计算机系统的物理内存管理。 NETCLIENT - 网络客户端管理。 NETLOGIN - 网络登录信息(属于特定用户)管理。 NETPROTOCOL - 协议(及其网络特征)管理。 NETUSE - 活动网络连接管理。 NIC - 网络接口控制器(NIC)管理。 NICCONFIG - 网络适配器管理。 NTDOMAIN - NT 域管理。 NTEVENT - NT 事件日志中的项目。 NTEVENTLOG - NT 事件日志文件管理。 ONBOARDDEVICE - 主板(系统板)中内置的通用适配器设备的管理。 OS - 已安装操作系统的管理。 PAGEFILE - 虚拟内存文件交换管理。 PAGEFILESET - 页面文件设置管理。 PARTITION - 物理磁盘的已分区区域的管理。 PORT - I/O 端口管理。 PORTCONNECTOR - 物理连接端口管理。 PRINTER - 打印机设备管理。 PRINTERCONFIG - 打印机设备配置管理。 PRINTJOB - 打印作业管理。 PROCESS - 进程管理。 PRODUCT - 安装程序包任务管理。 QFE - 快速修复工程。 QUOTASETTING - 卷上的磁盘配额设置信息。 RDACCOUNT - 远程桌面连接权限管理。 RDNIC - 对特定网络适配器的远程桌面连接管理。 RDPERMISSIONS - 特定远程桌面连接的权限。 RDTOGGLE - 远程打开或关闭远程桌面侦听程序。 RECOVEROS - 操作系统出现故障时将从内存收集的信息。 REGISTRY - 计算机系统注册表管理。 SCSICONTROLLER - SCSI 控制器管理。 SERVER - 服务器信息管理。 SERVICE - 服务应用程序管理。 SHADOWCOPY - 卷影副本管理。 SHADOWSTORAGE - 卷影副本存储区域管理。 SHARE - 共享资源管理。 SOFTWAREELEMENT - 系统上安装的软件产品元素的管理。 SOFTWAREFEATURE - SoftwareElement 的软件产品子集的管理。 SOUNDDEV - 声音设备管理。 STARTUP - 当用户登录到计算机系统时自动运行的命令的管理。 SYSACCOUNT - 系统帐户管理。 SYSDRIVER - 基本服务的系统驱动程序管理。 SYSTEMENCLOSURE - 物理系统外壳管理。 SYSTEMSLOT - 物理连接点(包括端口、插槽和外设以及专用连接点)的管理。 TAPEDRIVE - 磁带驱动器管理。 TEMPERATURE - 温度传感器(电子温度计)数据管理。 TIMEZONE - 时区数据管理。 UPS - 不间断电源(UPS)管理。 USERACCOUNT - 用户帐户管理。 VOLTAGE - 电压传感器(电子电压表)数据管理。 VOLUME - 本地存储卷管理。 VOLUMEQUOTASETTING - 将磁盘配额设置与特定磁盘卷相关联。 VOLUMEUSERQUOTA - 每用户存储卷配额管理。 WMISET - WMI 服务操作参数管理。 有关特定别名的详细信息,请键入: alias /? CLASS - 按 Esc 键可获取完整 WMI 架构。 PATH - 按 Esc 键可获取完整 WMI 对象路径。 CONTEXT - 显示所有全局开关的状态。 QUIT/EXIT - 退出程序。 有关 CLASS/PATH/CONTEXT 的详细信息,请键入: (CLASS | PATH | CONTEXT) /?
查询主板信息
- 查询主板全部信息(查询全部信息字段比较多,不太好查看,有些字段我们也不太关注,可以查询指定字段信息)
wmic BASEBOARD
- 查询主板指定字段信息
wmic BASEBOARD get Caption,Name,Product,SerialNumber,Version
- 查询结果
Caption Name Product SerialNumber Version 基板 基板 H110M-K 200873839101400 Rev X.0x
查询计算机系统信息
- Win32_ComputerSystem
- 查询计算机系统指定字段信息
wmic COMPUTERSYSTEM get Caption,UserName,SystemType
- 查询结果
Caption SystemType UserName DESKTOP-3PJ5ODO x64-based PC DESKTOP-3PJ5ODO\admin
查询CPU信息
- Win32_Processor
- 查询CPU指定字段信息(标题,频率,核心数,序列号)
wmic CPU get Caption,CurrentClockSpeed,SerialNumber,NumberOfCores
- 查询结果
Caption CurrentClockSpeed NumberOfCores SerialNumber Intel64 Family 6 Model 94 Stepping 3 2701 4 To Be Filled By O.E.M.
查询内存信息
- Win32_PhysicalMemory
- 查询内存指定字段信息(标题,内存大小,频率,内存厂商,序列号)
wmic MEMORYCHIP get Caption,Capacity,ConfiguredClockSpeed,Manufacturer,SerialNumber
- 查询结果
Caption Capacity ConfiguredClockSpeed Manufacturer SerialNumber 物理内存 17179869184 2133 A-DATA 31720500
查询硬盘信息
- Win32_DiskDrive
- 查询硬盘指定字段信息(标题,序列号,大小)
wmic DISKDRIVE get Caption,SerialNumber,Size
- 查询结果
Caption SerialNumber Size WDC WDS120G2G0A-00JH30 2039C2805287 120039736320 ST1000VX005-2EZ102 W9C4VT4Z 1000202273280
查询操作系统信息
Win32_OperatingSystem
查询操作系统指定字段信息(标题,厂商,架构,版本)
wmic OS get Caption,Manufacturer,OSArchitecture,Version
查询结果
Caption Manufacturer OSArchitecture Version Microsoft Windows 10 教育版 Microsoft Corporation 64 位 10.0.19045
查询账户信息
- 查询账户指定字段信息(标题,描述)
wmic USERACCOUNT get Caption,Description
- 查询结果
Caption Description DESKTOP-3PJ5ODO\admin DESKTOP-3PJ5ODO\Administrator 管理计算机(域)的内置帐户 DESKTOP-3PJ5ODO\DefaultAccount 系统管理的用户帐户。 DESKTOP-3PJ5ODO\Guest 供来宾访问计算机或访问域的内置帐户 DESKTOP-3PJ5ODO\lingp DESKTOP-3PJ5ODO\WDAGUtilityAccount 系统为 Windows Defender 应用程序防护方案管理和使用的用户帐户。
查询进程信息
- Win32_Process
- 查询进程指定字段信息(标题,名称,命令行参数,执行路径,进程ID,占用内存大小)
wmic PROCESS get Caption,Name,CommandLine,ExecutablePath,ProcessId,VirtualSize
- 查询指定进程的指定字段信息(查询全部进程信息结果内容较多,还可以查询指定进程的指定字段信息,这里指定查询记事本进程信息)
wmic PROCESS where "Name='notepad.exe'" get Caption,Name,CommandLine,ExecutablePath,ProcessId,VirtualSize
- 查询结果
Caption CommandLine ExecutablePath Name ProcessId VirtualSize notepad.exe "C:\WINDOWS\system32\NOTEPAD.EXE" C:\Users\admin\Desktop\tcp.txt C:\WINDOWS\system32\NOTEPAD.EXE notepad.exe 18788 2203494707200
说明
- 这里只列举了查询的部分主机信息,其他信息查询可参考帮助命令。
API使用
相关API介绍
- 初始化COM库
/* * @brief 初始化COM库 * @param [IN] pvReserved 保留参数,一般设置为0或者NULL * @param [IN] dwCoInit 初始化标志 * COINIT_MULTITHREADED 初始化多线程 COM 库,一般选择这个参数 * COINIT_APARTMENTTHREADED 初始化单线程 COM 库 * COINIT_DISABLE_OLE1DDE 禁用 OLE 1.0 动态数据交换 * COINIT_SPEED_OVER_MEMORY 选择速度而不是内存使用。这会导致在释放 COM 库时出现内存泄漏 * @return 返回S_OK表示成功 */ HRESULT CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
- 创建一个 COM 类的实例
/* * @brief 初始化COM库 * @param [IN] rclsid 要创建的 COM 类的 CLSID(类标识符), 建立与WMI的连接可使用 CLSID_WbemLocator 参数 * @param [IN] pUnkOuter 一般设置为0或者NULL * @param [IN] dwClsContext 指定组件应该加载到的上下文 * CLSCTX_INPROC_SERVER 组件应该加载到调用者的进程中。 * CLSCTX_INPROC_HANDLER 组件应该作为 in-process handler 加载。 * CLSCTX_LOCAL_SERVER 组件应该作为本地服务器进程加载。 * CLSCTX_REMOTE_SERVER 组件应该作为远程服务器进程加载。 * CLSCTX_ALL 组合了以上所有上下文。 * @param [IN] riid 请求的接口的 IID(接口标识符) * @param [OUT] ppv 指向接收创建的实例的接口指针的指针。如果函数成功,这个指针将指向请求的接口。 * @return 返回S_OK表示成功 */ HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,DWORD dwClsContext, REFIID riid, LPVOID FAR* ppv);
- 建立与WMI服务器的连接
/* * @brief 建立与WMI服务器的连接 * @param [IN] strNetworkResource 指定要连接的 WMI 服务器的网络资源名称,"ROOT\\CIMV2",表示连接到本地计算机的默认 WMI 命名空间。 * @param [IN] strUser 用于连接的用户名。如果是连接到本地计算机,可以设置为 NULL * @param [IN] strPassword 用于连接的密码。如果是连接到本地计算机,可以设置为 NULL * @param [IN] strLocale 指定连接的本地化设置。通常,这可以设置为 NULL,以使用系统的默认本地化设置。 * @param [IN] lSecurityFlags 指定安全标志,用于控制连接的安全性。通常,这可以设置为 WBEM_FLAG_CONNECT_USE_MAX_WAIT,表示使用最大等待时间。 * @param [IN] strAuthority 指定连接的授权信息。如果是连接到本地计算机,可以设置为 NULL。 * @param [IN] pCtx 一般设置为0或NULL * @param [OUT] ppNamespace 指向接收 IWbemServices 接口指针的指针。这个接口指针用于与 WMI 服务器进行交互。 * @return 返回S_OK表示成功 */ HRESULT IWbemLocator::ConnectServer(const BSTR strNetworkResource, const BSTR strUser, const BSTR strPassword, const BSTR strLocale, long lSecurityFlags,const BSTR strAuthority,IWbemContext *pCtx, IWbemServices **ppNamespace);
- 设置代理和安全控制
/* * @brief 设置代理和安全控制 * @param [IN] pProxy 指向要设置安全属性的 COM 对象的 IUnknown 接口的指针 * @param [IN] dwAuthnSvc 指定认证服务。通常设置为 RPC_C_AUTHN_WINNT,表示使用 Windows NT 认证。 * @param [IN] dwAuthzSvc 指定授权服务。通常设置为 RPC_C_AUTHZ_NONE,表示不使用授权服务。 * @param [IN] pServerPrincName 指定服务器主体名称,可设置为NULL * @param [IN] dwAuthnLevel 指定认证级别。例如,RPC_C_AUTHN_LEVEL_CALL 表示对每个调用进行认证。 * @param [IN] dwImpLevel 指定模拟级别。例如,RPC_C_IMP_LEVEL_IMPERSONATE 表示在调用期间模拟客户端的安全上下文。 * @param [IN] pAuthInfo 指定认证信息。通常设置为 NULL。 * @param [IN] dwCapabilities 指定代理的能力。例如,EOAC_NONE 表示没有额外的能力。 * @return 返回S_OK表示成功 */ WINOLEAPI CoSetProxyBlanket(IUnknown *pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR *pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
- 执行一个WMI查询
/* * @brief 执行一个 WMI 查询 * @param [IN] strQueryLanguage 指定查询语言,对于 WQL 查询,这个参数应该是字符串 "WQL" * @param [IN] strQuery 指定要执行的 WQL 查询字符串 * @param [IN] lFlags 指定查询标志,用于控制查询的行为。 * WBEM_FLAG_RETURN_IMMEDIATELY 表示查询应该立即返回,即使数据尚未完全可用。 * WBEM_FLAG_FORWARD_ONLY 表示查询应该使用前向only枚举,这样可以提高性能。 * @param [IN] pCtx 一般设置为NULL * @param [out] ppEnum 指向接收 IEnumWbemClassObject 接口指针的指针。这个接口指针用于枚举查询结果。 * @return 返回S_OK表示成功 */ HRESULT IWbemServices::ExecQuery(const BSTR strQueryLanguage, const BSTR strQuery, long lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum)
- 从枚举器中获取下一个WMI对象
/* * @brief 从枚举器中获取下一个WMI对象 * @param [IN] lTimeout 超时设置,可设置为WBEM_INFINITE * @param [IN] uCount 指定你想要获取的对象数 * @param [OUT] apObjects 指向一个 IWbemClassObject 接口指针的数组,用于接收获取的对象。 * @param [OUT] puReturned 指向一个 ULONG 类型的指针,用于接收实际获取的对象数 * @return 返回S_OK表示成功 */ HRESULT IEnumWbemClassObject::Next(long lTimeout, ULONG uCount, IWbemClassObject **apObjects, ULONG *puReturned)
- 从WMI类对象中获取属性值
/* * @brief 从WMI类对象中获取属性值 * @param [IN] wszName 指定要获取的属性的名称。比如Caption、Name等 * @param [IN] lFlags 可设置为0 * @param [IN,OUT] pVal 用于接收属性的值。 * @param [IN,OUT] pType 可设置为0 * @param [IN,OUT] plFlavor 可设置为0 * @return 返回S_OK表示成功 */ HRESULT IWbemClassObject::Get(LPCWSTR wszName, long lFlags, VARIANT *pVal, CIMTYPE *pType, long *plFlavor)
特别说明
- ExecQuery接口说明
- ExecQuery 接口第二个参数需要传入一个WQL查询语句,WQL语句格式与SQL语句比较类似
SELECT 指定字段名 FROM 要查询的信息 WHERE 属性 ='属性值'
- 比如要查询操作系统信息
SELECT * FROM Win32_OperatingSystem
- 查询操作系统信息的Caption字段
SELECT Caption FROM Win32_OperatingSystem
- 查询进程信息(记事本进程)
SELECT * FROM Win32_Process where Name = 'notepad.exe'
- 可以查询的信息都有哪些,可以在这里查看 要查询的信息介绍
- 或者使用命令行查询时,获取的结果中 CreationClassName 字段,就是这里要指定的值
编程示例
查询操作系统信息
#include <wbemidl.h> #include <TlHelp32.h> #include <comdef.h> #include <iostream> #include <vector> #pragma comment(lib, "WbemUuid.lib") int Wchar2Char(char* charStr, const wchar_t* wcharStr); int Char2Wchar(wchar_t* wcharStr, const char* charStr); int main(){ IWbemLocator* pLocator = NULL; IWbemServices* pServices = NULL; IEnumWbemClassObject* pEnumerator = NULL; IWbemClassObject* pClassObject = NULL; std::vector<std::string> vecNameList; // 初始化COM库 HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres) && (hres == RPC_E_TOO_LATE)) { return -1; } // 创建一个COM类的实例 hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator); if (FAILED(hres)) { CoUninitialize(); return -1; } // 建立与 WMI服务器的连接 hres = pLocator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pServices); if (FAILED(hres)) { pLocator->Release(); CoUninitialize(); return -1; } // 设置代理或者安全控制 hres = CoSetProxyBlanket(pServices, 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)) { pServices->Release(); pLocator->Release(); CoUninitialize(); return -1; } // 设置查询语句 char query[256] = { 0 }; strcpy(query, "SELECT * FROM Win32_OperatingSystem"); // 设置要查询的字段,传给Get接口 std::vector<std::string> vecKey; vecKey.push_back("Caption"); vecKey.push_back("Manufacturer"); vecKey.push_back("OSArchitecture"); // 执行WMI查询 hres = pServices->ExecQuery(_bstr_t(L"WQL"), _bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { pServices->Release(); pLocator->Release(); CoUninitialize(); return -1; } IWbemClassObject *pclsObj; ULONG uReturn = 0; bool bRet = false; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if ((0 == uReturn) || (0 == pclsObj)) { break; } int nIdx = 0; VARIANT vtProp; for(std::vector<std::string>::iterator it = vecKey.begin(); it != vecKey.end(); it++){ wchar_t *Item = new wchar_t[strlen((*it).c_str()) + 1]; Char2Wchar(Item, (const char*)(*it).c_str()); wchar_t content[MAX_PATH] = {0}; VariantInit(&vtProp); vtProp.bstrVal = 0; hr = pclsObj->Get((LPCWSTR)Item, 0, &vtProp, 0, 0); char *descBuf = new char[MAX_PATH]; memset(descBuf, 0, MAX_PATH); switch (vtProp.vt) { case VT_BSTR: wcscpy(content, vtProp.bstrVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I2: swprintf(content, sizeof(content) - 1, L"%d", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I4: swprintf(content, sizeof(content) - 1, L"%ld", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I8: swprintf(content, sizeof(content) - 1, L"%lld", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; } VariantClear(&vtProp); if(strlen(descBuf) != 0){ // 打印结果 printf("%s\n", descBuf); } delete []descBuf; delete []Item; } } pEnumerator->Release(); pServices->Release(); pLocator->Release(); CoUninitialize(); system("pause"); return 0; } int Wchar2Char(char* charStr, const wchar_t* wcharStr){ int len= WideCharToMultiByte(CP_ACP ,0, wcharStr, wcslen(wcharStr), NULL,0, NULL ,NULL ); WideCharToMultiByte(CP_ACP ,0, wcharStr, wcslen(wcharStr), charStr, len, NULL ,NULL ); charStr[len]= '\0'; return len; } int Char2Wchar(wchar_t* wcharStr, const char* charStr){ int len = MultiByteToWideChar(CP_ACP, 0, charStr, strlen(charStr), NULL, 0); MultiByteToWideChar(CP_ACP, 0, charStr, strlen(charStr), wcharStr, len); wcharStr[len]= '\0' ; return len; }
查询结果
Microsoft Windows 10 教育版 Microsoft Corporation 64 位 请按任意键继续. . .
判断指定启动参数的进程是否启动
#include <wbemidl.h> #include <TlHelp32.h> #include <comdef.h> #include <iostream> #include <vector> #pragma comment(lib, "WbemUuid.lib") int Wchar2Char(char* charStr, const wchar_t* wcharStr); int Char2Wchar(wchar_t* wcharStr, const char* charStr); bool processIsRunning(char* processName, char* processParam, bool& isRunning); int main(){ char processName[] = "notepad.exe"; char processParam[] = "tcp.txt"; bool isRunning = false; // 查询记事本是否启动,并且启动的文件为tcp.txt processIsRunning(processName, processParam, isRunning); if(isRunning){ printf("%s is running, param is %s\n", processName, processParam); } system("pause"); return 0; } int Wchar2Char(char* charStr, const wchar_t* wcharStr){ int len= WideCharToMultiByte(CP_ACP ,0, wcharStr, wcslen(wcharStr), NULL,0, NULL ,NULL ); WideCharToMultiByte(CP_ACP ,0, wcharStr, wcslen(wcharStr), charStr, len, NULL ,NULL ); charStr[len]= '\0'; return len; } int Char2Wchar(wchar_t* wcharStr, const char* charStr){ int len = MultiByteToWideChar(CP_ACP, 0, charStr, strlen(charStr), NULL, 0); MultiByteToWideChar(CP_ACP, 0, charStr, strlen(charStr), wcharStr, len); wcharStr[len]= '\0' ; return len; } bool processIsRunning(char* processName, char* processParam, bool& isRunning){ IWbemLocator* pLocator = NULL; IWbemServices* pServices = NULL; IEnumWbemClassObject* pEnumerator = NULL; IWbemClassObject* pClassObject = NULL; std::vector<std::string> vecNameList; // 初始化COM库 HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres) && (hres == RPC_E_TOO_LATE)) { return false; } // 创建一个COM类的实例 hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator); if (FAILED(hres)) { CoUninitialize(); return false; } // 建立与 WMI服务器的连接 hres = pLocator->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pServices); if (FAILED(hres)) { pLocator->Release(); CoUninitialize(); return false; } // 设置代理或者安全控制 hres = CoSetProxyBlanket(pServices, 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)) { pServices->Release(); pLocator->Release(); CoUninitialize(); return false; } // 查询指定进程信息 char query[256] = { 0 }; sprintf(query, "SELECT * FROM Win32_Process where Name = '%s'", processName); // 查询指定进程的命令行参数 std::vector<std::string> vecKey; vecKey.push_back("CommandLine"); // 执行WMI查询 hres = pServices->ExecQuery(_bstr_t(L"WQL"), _bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { pServices->Release(); pLocator->Release(); CoUninitialize(); return false; } IWbemClassObject *pclsObj; ULONG uReturn = 0; bool bRet = false; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if ((0 == uReturn) || (0 == pclsObj)) { break; } int nIdx = 0; VARIANT vtProp; for(std::vector<std::string>::iterator it = vecKey.begin(); it != vecKey.end(); it++){ wchar_t *Item = new wchar_t[strlen((*it).c_str()) + 1]; Char2Wchar(Item, (const char*)(*it).c_str()); wchar_t content[MAX_PATH] = {0}; VariantInit(&vtProp); vtProp.bstrVal = 0; hr = pclsObj->Get((LPCWSTR)Item, 0, &vtProp, 0, 0); char *descBuf = new char[MAX_PATH]; memset(descBuf, 0, MAX_PATH); switch (vtProp.vt) { case VT_BSTR: wcscpy(content, vtProp.bstrVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I2: swprintf(content, sizeof(content) - 1, L"%d", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I4: swprintf(content, sizeof(content) - 1, L"%ld", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; case VT_I8: swprintf(content, sizeof(content) - 1, L"%lld", vtProp.intVal); Wchar2Char(descBuf, (const wchar_t*)content); break; } VariantClear(&vtProp); if(strlen(descBuf) != 0){ // 打印结果 printf("%s\n", descBuf); std::string strValue(descBuf); // 判断启动参数是否为tcp.txt if(strValue.rfind("tcp.txt") != std::string::npos){ isRunning = true; break; } } delete []descBuf; delete []Item; } } pEnumerator->Release(); pServices->Release(); pLocator->Release(); CoUninitialize(); return true; }
结果
"C:\WINDOWS\system32\NOTEPAD.EXE" C:\Users\admin\Desktop\tcp.txt notepad.exe is running, param is tcp.txt 请按任意键继续. . .