是的,Windows上的Qt应用程序可以识别USB接入的设备是U盘还是鼠标。以下是实现方法:
1. 使用Windows API检测USB设备
可以通过Windows的设备管理接口来获取设备信息:
#include <windows.h>
#include <dbt.h>
#include <setupapi.h>
#include <devguid.h>
class USBDetector : public QWidget
{
public:
USBDetector(QWidget *parent = nullptr) : QWidget(parent)
{
// 注册接收设备变化消息
registerForDeviceNotifications();
}
private:
void registerForDeviceNotifications()
{
DEV_BROADCAST_DEVICEINTERFACE dbch;
ZeroMemory(&dbch, sizeof(dbch));
dbch.dbcc_size = sizeof(dbch);
dbch.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
HDEVNOTIFY hDevNotify = RegisterDeviceNotification(
(HANDLE)winId(),
&dbch,
DEVICE_NOTIFY_WINDOW_HANDLE
);
}
protected:
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override
{
MSG* msg = static_cast<MSG*>(message);
if (msg->message == WM_DEVICECHANGE) {
handleDeviceChange(msg->wParam, msg->lParam);
}
return QWidget::nativeEvent(eventType, message, result);
}
void handleDeviceChange(WPARAM wParam, LPARAM lParam)
{
if (wParam == DBT_DEVICEARRIVAL) {
// 设备插入
detectUSBDeviceType();
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
// 设备移除
qDebug() << "USB device removed";
}
}
};
2. 检测设备类型的方法
#include <initguid.h>
#include <cfgmgr32.h>
void USBDetector::detectUSBDeviceType()
{
HDEVINFO deviceInfoSet = SetupDiGetClassDevs(
NULL,
NULL,
NULL,
DIGCF_ALLCLASSES | DIGCF_PRESENT
);
if (deviceInfoSet == INVALID_HANDLE_VALUE) return;
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); i++) {
// 获取设备描述
char deviceDesc[256];
if (SetupDiGetDeviceRegistryPropertyA(
deviceInfoSet, &deviceInfoData, SPDRP_DEVICEDESC,
NULL, (PBYTE)deviceDesc, sizeof(deviceDesc), NULL)) {
QString desc = QString::fromLocal8Bit(deviceDesc);
// 判断设备类型
if (isStorageDevice(desc)) {
qDebug() << "USB Storage Device detected:" << desc;
emit usbStorageInserted(desc);
}
else if (isMouseDevice(desc)) {
qDebug() << "Mouse Device detected:" << desc;
emit mouseInserted(desc);
}
else if (isKeyboardDevice(desc)) {
qDebug() << "Keyboard Device detected:" << desc;
emit keyboardInserted(desc);
}
}
// 通过设备类GUID进一步判断
GUID classGuid;
if (SetupDiGetDeviceRegistryProperty(
deviceInfoSet, &deviceInfoData, SPDRP_CLASSGUID,
NULL, (PBYTE)&classGuid, sizeof(classGuid), NULL)) {
detectByClassGuid(classGuid);
}
}
SetupDiDestroyDeviceInfoList(deviceInfoSet);
}
bool USBDetector::isStorageDevice(const QString &desc)
{
return desc.contains("usb", Qt::CaseInsensitive) &&
(desc.contains("storage", Qt::CaseInsensitive) ||
desc.contains("disk", Qt::CaseInsensitive) ||
desc.contains("flash", Qt::CaseInsensitive));
}
bool USBDetector::isMouseDevice(const QString &desc)
{
return desc.contains("mouse", Qt::CaseInsensitive) ||
desc.contains("hid-compliant mouse", Qt::CaseInsensitive);
}
bool USBDetector::isKeyboardDevice(const QString &desc)
{
return desc.contains("keyboard", Qt::CaseInsensitive) ||
desc.contains("hid-compliant keyboard", Qt::CaseInsensitive);
}
void USBDetector::detectByClassGuid(const GUID &classGuid)
{
static const GUID diskClassGuid = {0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
if (IsEqualGUID(classGuid, diskClassGuid)) {
qDebug() << "Disk drive detected via GUID";
}
}
3. pro文件配置
在.pro文件中添加Windows库:
QT += core gui widgets
win32 {
LIBS += -lsetupapi -lcfgmgr32 -lole32
# Windows版本设置(可选)
# win32:greaterThan(QT_MAJOR_VERSION ,4): QT += winextras
}
4. 更简单的方法 - 使用QStorageInfo(仅存储设备)
#include <QStorageInfo>
#include <QTimer>
class SimpleUSBDetector : public QObject
{
public:
SimpleUSBDetector()
{
//定时检查存储设备变化
QTimer *timer = new QTimer(this);
connect(timer,&QTimer :: timeout , this ,&SimpleUSBDetector :: checkRemovableDrives );
timer -> start(2000);
}
private slots:
void checkRemovableDrives(){
auto drives=QStorageInfo :: mountedVolumes();
for(auto&drive:drives){
if(drive.isValid()&&drive.isReady()){
if(drive.fileSystemType().contains("fat")||drive.fileSystemType().contains("ntfs")){
qDebug()<<"Removable Drive:"<<drive.name();
}
}
}
}
};
⚠️注意事项:
- 管理员权限:某些操作可能需要管理员权限
- 代码签名:在生产环境中可能需要代码签名证书
- 兼容性:不同Windows版本可能有差异
这种方法可以准确区分U盘、鼠标、键盘等不同类型的USB设备。
内容由零声教学AI助手提供,问题来源于学员提问




