ZBLOG

QT WMI查询usb接入的设备属于U盘还是鼠标,或者打印机

在Qt中通过WMI查询USB设备类型,可以通过以下步骤实现:

1. 添加必要的头文件和库

#include <QCoreApplication>
#include <QDebug>
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

2. 完整的查询代码示例

QString getUSBDeviceType(const QString& pnpDeviceId)
{
    // 根据PNP设备ID判断设备类型
    if (pnpDeviceId.contains("USBSTOR", Qt::CaseInsensitive)) {
        return "U盘";
    } else if (pnpDeviceId.contains("HID", Qt::CaseInsensitive) && 
               pnpDeviceId.contains("VID", Qt::CaseInsensitive)) {
        return "鼠标";
    } else if (pnpDeviceId.contains("PRINTER", Qt::CaseInsensitive) || 
               pnpDeviceId.contains("PRN", Qt::CaseInsensitive)) {
        return "打印机";
    }
    return "其他USB设备";
}

void queryUSBDevices()
{
    HRESULT hres;
    
    // 初始化COM
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        qDebug() << "Failed to initialize COM library.";
        return;
    }
    
    // 设置COM安全级别
    hres = CoInitializeSecurity(
        NULL, -1, NULL, NULL,
        RPC_C_AUTHN_LEVEL_NONE,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL, EOAC_NONE, NULL
    );
    
    // 创建WMI实例
    IWbemLocator *pLoc = NULL;
    hres = CoCreateInstance(
        CLSID_WbemLocator, 0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator,
        (LPVOID *)&pLoc
    );
    
    if (FAILED(hres)) {
        qDebug() << "Failed to create IWbemLocator object.";
        CoUninitialize();
        return;
    }
    
    // 连接到WMI
    IWbemServices *pSvc = NULL;
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // WMI命名空间
        NULL, NULL, 0, NULL, 0, 0, &pSvc
    );
    
    if (FAILED(hres)) {
        qDebug() << "Could not connect to WMI.";
        pLoc->Release();
        CoUninitialize();
        return;
    }
    
    // 设置代理安全级别
    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)) {
        qDebug() << "Could not set proxy blanket.";
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;
    }
    
    // 执行查询 - Win32_USBControllerDevice获取关联关系
//     IEnumWbemClassObject* pEnumerator = nullptr;
//     hres = pSvc->ExecQuery(
//         bstr_t("WQL"),
//         bstr_t("SELECT * FROM Win32_USBControllerDevice"),
//         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
//         nullptr,
//         &pEnumerator);

	IEnumWbemClassObject* pEnumerator = nullptr;  
	hres = pSvc->ExecQuery(  
	    bstr_t("WQL"),  
	    bstr_t("SELECT * FROM Win32_PnPEntity WHERE PNPClass='USB'"),  
	    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,nullptr,&pEnumerator);  

	if (SUCCEEDED(hres))
	{
		IWbemClassObject* pclsObj = nullptr;
		ULONG uReturn = 0;

		while (pEnumerator)
		{
			hres = pEnumerator->Next(WBEM_INFINITE,1,&pclsObj,&uReturn);

			if(0 == uReturn)
				break;

			VARIANT vtProp{};

			//获取PNP设备ID作为关键识别信息  
			pclsObj->Get(L"PNPDeviceID",0,&vtProp,nullptr,nullptr);
			const auto device_id= QString::fromStdWString(vtProp.bstrVal);
            VariantClear(&vtProp);

            //获取设备名称(描述)
            VARIANT vtName{};
            BSTR nameProperty=L"Name";
            HRESULT hr=pclsObj->Get(nameProperty ,0,&vtName,nullptr,nullptr);
            
            const auto device_name=SUCCEEDED(hr)?
                QString::fromStdWString(vtName.bstrVal):QStringLiteral("");
            
            VariantClear(&vtName);

			const auto device_type=getUSBDeviceType(device_id);

			qDebug()<<"发现USB设备:"
				   <<"\n  名称:"<<device_name 
                   <<"\n  设备ID:"<<device_id 
                   <<"\n  类型:"<<device_type<<"\n";

			pclsObj->Release();
		}
		
		pEnumerator->Release();
	}
	else{
	    qDebug()<<"Query for USB devices failed.";
	}
	
	pSvc->Release();  
	pLoc->Release();  
	
	qDebug()<<"枚举完成";  

}

##3 . pro文件配置

在.pro文件中添加:

win32: LIBS += -lole32 -loleaut32 -luuid -lwbemuuid -ladvapi32

CONFIG += console c++11

QT -= gui
QT += core

##4 .使用示例

int main(int argc ,char *argv[])
{
 QCoreApplication app(argc ,argv); 

 queryUSBDevices();

 return app.exec(); 
} 

##5 .更精确的设备分类方法

如果需要更精确的分类,可以结合多个WMI类:

void preciseUSBAnalysis()
{
 //Win32_DiskDrive-物理磁盘(可区分U盘)
 //Win32_Printer-打印机设备  
 //Win32_PointingDevice-指针设备(鼠标等)   
}

这种方法通过分析设备的PNP Device ID来识别类型:

  • U盘:包含”USBSTOR”标识符
  • 鼠标:包含”HID”(人机接口设备)和”VID”(厂商ID)
  • 打印机:包含”PRINTER”或”PRN”标识符


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24427

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?