当前位置:网站首页>Qt combat | how to access the USB device information?
Qt combat | how to access the USB device information?
2022-07-29 15:37:00 【Li Xiaoyao】
关注、星标公众号,直达精彩内容
文章出处:Qt小罗
整理:李肖遥
1 需求描述
实现USBHotplug state testing of the equipment;
可识别USB设备信息,例如PID、VID、设备序列号等.
几年前在CSDN上分享过,被CSDN恶心到了,Randomly set points,Disguised to allow users to charge money,Now rearrange the code to share,希望能帮到需要的人.
2 设计思路
2.1 获取USBdevice information?
经过查询,QtDevice-related information can be obtained through local events,The event function prototype used is:
bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
官方说明:This special event handler can be reimplemented in subclasses,To receive in the message parameter passed byeventType标识的本机平台事件.In the reimplementation of this function,if you want to stopQt正在处理的事件,请返回true并设置result,The result parameter is onlyWindows上有意义.如果返回false,This native event will be delivered backQt,Qtconvert the event toQtevent and send it to the window.
注意:It is only when the window has a local window handle,events are delivered to this event handler.
很容易理解吧,对于widget窗口而言,This event is the source,QtPackaged events come from here,如果直接返回trueThe interface will not be displayed,有兴趣的朋友可以试试.另外,Found that the event is notQWidget的,So only the window interface has,The handle of the window can be accessed viaQWidget::winId获取到,Behind the register equipment will be used.
2.2 准备工作?
如果只是重写nativeEvent是不够的,No device information can be obtained,Can only identify hotplug state.要识别USBDevice information needs to be usedGUID,pre-defined deviceGUID,re-register the device,Only after the registration is complete can the local events of the corresponding device be obtained,To obtain device information through events.
GUID(全称:Globally Unique Identifier)全局唯一标识符,在windows上使用GUID来管理设备,驱动,总线,类型,块设备,电源等.
2.3 Common hardware devicesGUID
Identifier | Class GUID |
---|---|
GUID_DEVINTERFACE_USB_DEVICE | {A5DCBF10-6530-11D2-901F-00C04FB951ED} |
GUID_DEVINTERFACE_USB_HOST_CONTROLLER | {A5DCBF10-6530-11D2-901F-00C04FB951ED} |
GUID_DEVINTERFACE_USB_HUB | {F18A0E88-C30C-11D0-8815-00A0C906BED8} |
GUID_DEVINTERFACE_NET | {CAC88484-7515-4C03-82E6-71A87ABAC361} |
GUID_DEVINTERFACE_DISK | {53F56307-B6BF-11D0-94F2-00A0C91EFB8B} |
GUID_DEVINTERFACE_CDROM | {53F56308-B6BF-11D0-94F2-00A0C91EFB8B} |
GUID_DEVINTERFACE_KEYBOARD | {884B96C3-56EF-11D1-BC8C-00A0C91405DD} |
GUID_DEVINTERFACE_MOUSE | {378DE44C-56EF-11D1-BC8C-00A0C91405DD} |
GUID_DEVINTERFACE_IMAGE | {6BDD1FC6-810F-11D0-BEC7-08002BE2092F} |
GUID_BTHPORT_DEVICE_INTERFACE | {0850302A-B344-4fda-9BE9-90576B8D46F0} |
太多了,网上可以搜到,这里就不一一列出. |
3 代码实现
windowsProvides an interface to register devices with the system,After registrationU盘插拔(或其它volume增删)的时候,will be sent to the registered windowWM_DEVICECHANGE消息:
HDEVNOTIFY WINAPI RegisterDeviceNotification(
__in HANDLE hRecipient, // Can be a window handle or a service handle
__in LPVOID NotificationFilter,
__in DWORD Flags // 制定hRecipient是窗口句柄,or service handle
);
先注册设备,这样才能接收到消息,代码如下:
void Dialog::registerDevice() { const GUID GUID_DEVINTERFACE_LIST[] = { { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }, //USB设备的GUID { 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } }}; HDEVNOTIFY hDevNotify; DEV_BROADCAST_DEVICEINTERFACE NotifacationFiler; ZeroMemory(&NotifacationFiler,sizeof(DEV_BROADCAST_DEVICEINTERFACE)); NotifacationFiler.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotifacationFiler.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; for (int i = 0; i < sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID); i++) { NotifacationFiler.dbcc_classguid = GUID_DEVINTERFACE_LIST[i]; hDevNotify = RegisterDeviceNotification((HANDLE)this->winId(), &NotifacationFiler, DEVICE_NOTIFY_WINDOW_HANDLE); if (!hDevNotify) { qCritical() << QStringLiteral("注册失败!"); } } }
Get news and parse through local events,代码如下:
bool Dialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
Q_UNUSED(eventType);
Q_UNUSED(result);
MSG *msg = reinterpret_cast<MSG *>(message);
int msgType = msg->message;
if (WM_DEVICECHANGE == msgType) {
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
switch (msg->wParam) {
case DBT_DEVICEARRIVAL:
{
if (DBT_DEVTYP_VOLUME == lpdb->dbch_devicetype) {
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (0 == lpdbv->dbcv_flags) { //优盘
QString USBDisk = QString(this->firstDriveFromMask(lpdbv ->dbcv_unitmask));
ui->labelShowMsg->setText(QString(QStringLiteral("已检测到USB设备插入--盘符:<%1>")).arg(USBDisk));
} else if (DBTF_MEDIA == lpdbv->dbcv_flags) {
qDebug() << "CD_Arrived.";
}
} else if (DBT_DEVTYP_DEVICEINTERFACE == lpdb->dbch_devicetype) {
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)lpdb;
QString name = QString::fromWCharArray(pDevInf->dbcc_name);
if (!name.isEmpty()) {
if (name.contains("USBSTOR")) {
QStringList listAll = name.split('#');
QStringList listInfo = listAll.at(1).split('&');
m_usbInfoList.append(listInfo.at(1).mid(4)); //设备制造商 3
m_usbInfoList.append(listInfo.at(2).mid(5)); //设备型号 4
m_usbInfoList.append(listInfo.at(3).mid(4)); //设备版本 5
} else {
m_usbInfoList.clear();
QStringList listAll = name.split('#');
QStringList listID = listAll.at(1).split('&');
m_usbInfoList.append(listID.at(0).right(4)); //vid 0
m_usbInfoList.append(listID.at(1).right(4)); //pid 1
m_usbInfoList.append(listAll.at(2)); //设备序列号 2
}
}
display();
}
}
break;
case DBT_DEVICEREMOVECOMPLETE:
{
if (DBT_DEVTYP_VOLUME == lpdb->dbch_devicetype) {
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (0 == lpdbv->dbcv_flags) {
ui->labelShowMsg->setText(QString(QStringLiteral("USB设备已拔出!")));
QTimer::singleShot(1000, ui->labelShowMsg, SLOT(clear()));
}
if (DBTF_MEDIA == lpdbv->dbcv_flags) {
ui->labelShowMsg->setText("CD_Removed.");
}
}
}
break;
}
}
return false;
}
折叠
补充下,获取到的USBThe original data of device information is as follows,Through the above code parsing,然后显示到界面上.
"\\\\?\\USB#VID_0951&PID_1666#E0D55EA574B4F371679B1A6D#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
"\\\\?\\USBSTOR#Disk&Ven_Kingston&Prod_DataTraveler_3.0&Rev_#E0D55EA574B4F371679B1A6D&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}"
发现没有,这个GUIDIs it the same as what we registered?,feel it.If you want to get information about other devices,Registration is indispensable,不然就获取不到.再有一个就是,Equipment information is not an event would get out of,从上可以看出,It takes two events here to get the complete information,That is, registered two devices,可以尝试将GUID_DEVINTERFACE_LISTRemove a listGUID,结果是USBEquipment information is not complete.
3 总结
By registering the device、receive local events、Parse the event message,Finally, device information can be obtained.If you want to further implement special functions,Such as custom borderless stretching、移动等,Can also be achieved by local events,这需要对windowsThe message mechanism can be further studied.当然也可以使用QtEncapsulated events for processing,都是事件,What kind of tricks you can play depends on your own ability..到这里对windowsThere should be a preliminary understanding of the message mechanism,还是那句话,Have a good start is always important.
版权声明:本文来源网络,免费传达知识,版权归原作者所有.如涉及作品版权问题,请联系我进行删除.
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“加群”按规则加入技术交流群.
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看.
边栏推荐
- error #6633: The type of the actual argument differs from the type of the dummy argument.
- 数据分析(二)
- File management: logical structure
- 文档贡献与写作必读-OpenHarmony开发者文档风格指南
- I/O Code Practice
- 广汽本田安全驾驶体验营,老司机的必修课
- Why does APP use the JSON protocol to interact with the server: serialization related knowledge
- NDK 系列(5):JNI 从入门到实践,爆肝万字详解!
- 令人难以置信的DeepMind数据库现在包括了科学界已知的几乎所有蛋白质
- Linux安装MySQL(超详细)
猜你喜欢
随机推荐
药品研发--质理研究人员绩效办法
数据库管控平台-awr报告采集(mysql/oracle)
Learning Policies for Adaptive Tracking with Deep Feature Cascades全文翻译
I quit my job after cutting the brothers, and turned to do a small clerk
gateway基本使用
【LeetCode】1. 两数之和
Google Play 政策更新 | 2022 年 7 月
【 LeetCode 】 350. The intersection of two arrays. II
半导体行业集团采购管理系统:简化企业采购流程,以数字化畅通采购信息渠道
数商云SCM供应链系统方案服务亮点:生产管理更智能、产业供应链协同管理更便捷
云原生Meetup·广州站举行,共话云原生时代的企业数字化转型
UFLO:5、启动任务并自动完成第一个人工任务
ES6 from entry to master # 11: the Map data type
如何创建NFT(还在创作中ing)
如何获取本地json
深度卷积生成对抗网络
uni 的下拉式筛选菜单的功能/图片懒加载
BGP federation experiment
不会多线程还想进BAT?精选19道多线程面试题,有答案边看边学
关于数字化转型 你需要知道的八项指导原则