在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助手提供,问题来源于学员提问




