ZBLOG

Windows QT可以识别usb接入的设备属于U盘还是鼠标,或者打印机

在Windows平台上,使用Qt识别USB设备类型(如U盘、鼠标、打印机)可以通过以下几种方式实现:


1. 使用Windows API + Qt

Qt本身没有直接提供USB设备类型检测的接口,但可以通过调用Windows API获取设备信息,再与Qt结合。

步骤:

  1. 获取设备信息
    使用SetupAPI(设备安装函数)枚举USB设备,获取设备的GUID和设备实例句柄。
  2. 解析设备属性
    通过设备属性(如DeviceDescHardwareIDCompatibleIDs)判断设备类型。

示例代码:

#include <windows.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <QDebug>

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

void checkUSBDevices() {
    HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, L"USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE) return;

    SP_DEVINFO_DATA devInfoData;
    devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData); i++) {
        WCHAR deviceName[256];
        DWORD size = 0;

        // 获取设备描述
        if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_DEVICEDESC, NULL,
                                            (PBYTE)deviceName, sizeof(deviceName), &size)) {
            QString desc = QString::fromWCharArray(deviceName).toLower();

            // 简单关键词匹配(实际需更精确的规则)
            if (desc.contains("storage") || desc.contains("usb drive")) {
                qDebug() << "U盘:" << desc;
            } else if (desc.contains("mouse")) {
                qDebug() << "鼠标:" << desc;
            } else if (desc.contains("printer")) {
                qDebug() << "打印机:" << desc;
            }
        }
    }
    SetupDiDestroyDeviceInfoList(hDevInfo);
}

2. 使用WMI查询(推荐)

WMI(Windows Management Instrumentation)可以更系统地获取硬件信息。

步骤:

  1. 使用WMI查询Win32_USBHubWin32_KeyboardWin32_Printer等类。
  2. 通过Qt的QAxObject调用WMI接口(需启用ActiveQt模块)。

示例代码:

#include <QAxObject>
#include <QDebug>

void queryWMI() {
    QAxObject* wmi = new QAxObject("WbemScripting.SWbemLocator");
    QAxObject* services = wmi->querySubObject("ConnectServer(QString)", "root\\cimv2");

    // 查询存储设备
    QAxObject* items = services->querySubObject("ExecQuery(QString)", 
        "SELECT * FROM Win32_LogicalDisk WHERE DriveType=2");
    
    int count = items->property("Count").toInt();
    for (int i = 0; i < count; ++i) {
        QAxObject* item = items->querySubObject("ItemIndex", i);
        qDebug() << "U盘:" << item->property("DeviceID").toString();
        delete item;
    }

    // 查询鼠标(需管理员权限)
    QAxObject* mice = services->querySubObject("ExecQuery(QString)", 
        "SELECT * FROM Win32_PointingDevice");
    
    count = mice->property("Count").toInt();
    for (int i = 0; i < count; ++i) {
        QAxObject* item = mice->querySubObject("ItemIndex", i);
        qDebug() << "鼠标:" << item->property("Name").toString();
        delete item;
    }

    delete items;
    delete mice;
    delete services;
    delete wmi;
}

3. 使用第三方库(libusb)

通过libusb库直接与USB设备通信,读取设备描述符中的设备类(bDeviceClass)接口类(bInterfaceClass)

关键分类码:

  • 0x08: Mass Storage(U盘)
  • 0x03: HID(鼠标/键盘)
  • 0x07: Printer

注意事项:

  1. 权限问题
    WMI和设备枚举可能需要管理员权限。
  2. 动态监测
    如需实时监测USB热插拔,可监听Windows消息WM_DEVICECHANGE,并在Qt中重写nativeEvent方法。
  3. 跨平台限制
    上述方法仅适用于Windows,Linux需使用udev等机制。

如果需要完整的项目示例或进一步优化,请参考零声教育相关课程中的《Qt高级开发》章节。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?