WMI技术介绍以及使用WMI技术获取系统信息

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
        请按任意键继续. . .
      

相关推荐

  1. WMI技术介绍以及使用WMI技术获取系统信息

    2024-05-26 03:34:54       12 阅读
  2. 反射技术介绍以及底层逻辑使用

    2024-05-26 03:34:54       10 阅读
  3. 基于单片机和Wi-Fi 技术的家电远程控制系统设计

    2024-05-26 03:34:54       16 阅读
  4. 改善Wi-Fi信号的8个技巧,看下有没有适合你的

    2024-05-26 03:34:54       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-26 03:34:54       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-26 03:34:54       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-26 03:34:54       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-26 03:34:54       18 阅读

热门阅读

  1. 黄金价格创新高,交易风险提示

    2024-05-26 03:34:54       11 阅读
  2. gateway基本配置

    2024-05-26 03:34:54       10 阅读
  3. 时政|杂粮产业

    2024-05-26 03:34:54       13 阅读
  4. MYSQL--多表查询

    2024-05-26 03:34:54       9 阅读
  5. Gopeed的高级用法

    2024-05-26 03:34:54       13 阅读
  6. GitLab的原理及应用详解(四)

    2024-05-26 03:34:54       11 阅读
  7. 揭秘软件测试工程师:事业前景和成功秘诀

    2024-05-26 03:34:54       10 阅读