4

我想监视运行 Windows 的计算机的 USB 总线以查找(拔出)插入事件。当设备被(未)插入时,我想知道它的 USB 地址、供应商 ID、根集线器 ID 和设备上方的集线器端口。例如 usb_addr: 10, vendor_id: 1234, product_id: 5678, bus_id: 2, port_path: 5/4/3

这意味着它是总线 id 2 端口 5 上的设备,并且插入了另一个集线器,并且在该集线器的端口 4 上有另一个集线器,并且在该集线器的端口 3 上是正在报告的设备。

我正在尝试编写一小段特定于操作系统的代码来进行 USB 设备热插拔检测,以集成到更大的跨平台(Linux、Windows、Mac)测试程序中。使用这个热插拔代码的代码是用 Python 3 编写的,所以我更愿意用 Python 编写热插拔代码,但我在这方面有点灵活,但我真的想避免任何需要我付费的事情执照。

似乎有两个主要选择:

我看过一些关于 Windows API 函数 RegisterDeviceNotification 的讨论,但我不清楚是否可以注册以接收所有 USB 设备的事件,或者您是否需要知道特定设备接口的 GUID(例如键盘、老鼠等)。如果是这样的话,这个解决方案似乎不起作用,因为我想监控所有 USB 设备。

另一种选择似乎涉及一种称为“WMI”的东西,它似乎主要是在讨论“托管”代码时出现的,这将迫使我用 C# 或 IronPython 等 .NET 语言编写这个组件。这个问题(Get List of connected USB Devices)询问如何查询 USB 设备并提供了一个示例,但它不处理热插拔事件,用户“Nedko”建议应该使用类Win32_USBControllerDevice而不是 Win32_USBHub。我真的不明白 Win32_USBControllerDevice 对象的实际模型。似乎 Dependent 成员可能是对 CIM_LogicalDevice 对象的引用,但即便如此,它似乎也缺少我正在寻找的 USB 特定信息。

我应该查看哪些 API 来解决这个问题?

4

1 回答 1

1

您看到的是 USB 设备类。还有接口类。传递GUID_DEVINTERFACE_USB_DEVICE( usbiodef.h, 驱动程序文档) 为任何 USB 活动生成事件。另一个可能的候选GUID_DEVCLASS_USB对象,似乎是用于无法识别的 USB 设备。我在测试期间无法触发它。

请注意,Doran Holan(Microsoft 开发人员)的一篇文章似乎声称传递接口类 GUID 不起作用。他的文章来自 2006 年,在发布此答案(2009 年)之前,声称我详述的方法是有效的。

如果您需要与 Windows 的低级功能进行交互,您将面临一场艰苦的战斗,试图从 Python 中进行(大约 2018 年)。IronPython 可能表现不错。C# 是命中注定的——通常你会发现缺少重要的功能。任何给定库的绑定通常都无法正常工作。

要像在 C# 中一样使用 C++ 中的 WMI(例如使用ManagementObjectSearcherand ManagementObject),您应该实例化IWbemServicesusingIWbemLocator::ConnectServer然后调用IWbemServices::ExecQuery.

您可以查看WMI C++ 应用程序示例以获取更多信息。

于 2018-05-31T15:22:34.777 回答