USB 设备热插拔的检测

本文介绍了在Windows系统中如何检测USB设备的热插拔,包括通过WM_DEVICECHANGE消息监听设备变动,使用SetupDiXxx() API枚举设备,以及注册DeviceNotification()以获取详细设备信息。此外,还探讨了设备类GUID和设备接口GUID的区别,并提供了禁用设备的方法及程序测试情况。
摘要由CSDN通过智能技术生成

系统检测USB 设备往往分为两个过程:


1. USB 设备已经插入, 打开软件。 此时需要枚举当前设备列表中所有的设备,并过滤指定的USB 设备。

2. 打开软件后, USB 热插拔 。 此时用WM_DEVICECHANGE 消息去获取设备信息。 当设备插入或者移除时,系统给当前主窗口发送WM_DEVICECHANGE 消息 。 注意: 默认状态, 任何设备都会通知。 所以需要注册指定的通知消息。


第一种:枚举系统中所有的USB 设备, 可根据 PID,VID 进一步做判断。

void CDataSyncAccessDlg::CollectUSBInfo()
{
	// 获取当前系统所有使用的设备
	DWORD dwFlag = (DIGCF_ALLCLASSES | DIGCF_PRESENT);
	HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, dwFlag);
	if (INVALID_HANDLE_VALUE == hDevInfo)
	{
		AfxMessageBox(_T("获取系统设备列表失败"));
		return;
	}

	// 准备遍历所有设备查找USB
	SP_DEVINFO_DATA sDevInfoData;
	sDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

	TCHAR szDIS[MAX_PATH]; // Device Identification Strings, 
	DWORD nSize = 0;
	for (int i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &sDevInfoData); i++)
	{
		nSize = 0;
		if (!SetupDiGetDeviceInstanceId(hDevInfo, &sDevInfoData, szDIS, sizeof(szDIS), &nSize))
		{
			AfxMessageBox(_T("获取设备识别字符串失败"));
			break;
		}
		// 设备识别串的前三个字符是否是"USB", 模板: USB\VID_XXXX&PID_XXXX\00000xxxxxxx
		CString strDIS(szDIS);
		strDIS.MakeUpper();
		if (strDIS.Left(3) == _T("USB"))
		{
			int pos = strDIS.ReverseFind('\\');
			CString DeviceSer = strDIS.Right(strDIS.GetLength() - pos-1);
			//匹配序列号
			if (ValidDevcie(DeviceSer))
			{
				SetUSBState(TRUE);
			}
		}
	}
	// 释放设备
	SetupDiDestroyDeviceInfoList(hDevInfo);
}


第二种: windows操作系统在检测到硬件变化时,会发送一个WM_DEVICECHANGE硬件change消息。因此,我们要做的就是在我们的程序中添加WM_DEVICECHANGE的消息响应。

BEGIN_MESSAGE_MAP(CHWDetectDlg, CDialog)zai
    // ... other handlers
    ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
END_MESSAGE_MAP()

LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
    // for more information, see MSDN help of WM_DEVICECHANGE
    // this part should not be very difficult to understand
    if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) {
        PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
        switch( pHdr->dbch_devicetype ) {
            case DBT_DEVTYP_DEVICEINTERFACE:
                PDEV_BROADCAST_DEVICEINTERFACE pDevInf = 
要在Qt中实现USB热插拔检测,可以使用QDeviceWatcher类。QDeviceWatcher是一个用于监测设备插入和移除事件的类。 首先,确保在项目文件(.pro)中添加以下内容以启用Qt的udev库: ```cpp LIBS += -ludev ``` 然后,可以按照以下步骤在Qt中实现USB热插拔检测: 1. 在头文件中包含必要的头文件: ```cpp #include <QObject> #include <QDeviceWatcher> ``` 2. 创建一个类并继承自QObject: ```cpp class USBWatcher : public QObject { Q_OBJECT public: explicit USBWatcher(QObject *parent = nullptr); private slots: void deviceAdded(const QString &devPath); void deviceRemoved(const QString &devPath); private: QDeviceWatcher *m_deviceWatcher; }; ``` 3. 在实现文件中定义构造函数,并在构造函数中初始化QDeviceWatcher对象,并连接相应的槽函数: ```cpp USBWatcher::USBWatcher(QObject *parent) : QObject(parent) { m_deviceWatcher = new QDeviceWatcher(this); connect(m_deviceWatcher, SIGNAL(deviceAdded(QString)), this, SLOT(deviceAdded(QString))); connect(m_deviceWatcher, SIGNAL(deviceRemoved(QString)), this, SLOT(deviceRemoved(QString))); m_deviceWatcher->start(); } ``` 4. 实现设备插入和移除的槽函数: ```cpp void USBWatcher::deviceAdded(const QString &devPath) { // 处理设备插入事件 qDebug() << "Device added: " << devPath; } void USBWatcher::deviceRemoved(const QString &devPath) { // 处理设备移除事件 qDebug() << "Device removed: " << devPath; } ``` 5. 在你的应用程序中实例化USBWatcher对象,并将其保持活动状态: ```cpp int main(int argc, char *argv[]) { QApplication app(argc, argv); USBWatcher usbWatcher; return app.exec(); } ``` 通过以上步骤,你现在可以在`deviceAdded()`和`deviceRemoved()`槽函数中处理设备插入和移除事件。你可以根据需求来执行一些自定义的操作,比如更新UI或者执行特定的任务。 请注意,USB热插拔检测需要在具有相应权限的操作系统上运行,如Linux。在不同的操作系统和平台上,可能需要使用不同的方法来实现设备监测。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值