我有一个USB设备,枚举与不同的接口,VID,PID和序列号时,命令这样做,我想跟踪发生这种变化后的物理设备。 我的想法是通过它的中心和港口位置进行跟踪。
Win32_PnPSignedDriver类有一个“Location”字段,看起来很完美(例如Port_#0001.Hub_#0010
),但是它只包含驱动程序第一次加载时的设备位置。 将硬件插入不同的端口不会更新该字段。
但是,由于在通过设备pipe理器查看设备时,“详细信息”(Details)选项卡下有“位置信息”(Location information)字段,因此信息可用。 可以通过WMI查询或其他方法检索这些信息吗? 有没有更好的方法来解决这个问题?
编辑:我知道这听起来像一个奇怪的场景。 这些器件中的微控制器包含一个枚举为CDC器件(即串行端口)的ROM,并允许编程。 在生产过程中,跟踪制造商的ROM(唯一的VID / PID /序列号)和我的定制固件接口(不同的VID / PID /序列号)之间的设备变化是有益的。
我知道这个答案已经有一段时间了,但是我正在做一个需要类似功能的项目,我可以告诉你,这确实是可能的。 据我所知,它确实需要DDK和PInvoke,这个信息没有C#或WMI接口。 它需要打开低级USB根集线器设备并直接向它们发送驱动程序IOCTL命令。
好消息是,微软提供了一个示例C ++应用程序,它可以完全枚举所有USB设备,并准确显示它们连接的端口。 该应用程序是USBView示例应用程序 。
我想你会发现,如果你编译和运行这个应用程序,你会发现它确实显示了你的设备插入的位置,如果你插入任何设备到该端口,它显示在同一个地方。 如果你创建一个非托管的C ++ DLL,提供一些C#应用程序可以用来获取所需信息的调用,可能会更容易一些。
它有这样的说法:它的代码中的“EnumerateHubPorts()”函数:
给定一个开放式集线器的句柄和集线器下游端口的数量,向集线器发送集线器每个下游端口的IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX请求,以获取有关连接到每个端口的设备(如果有)的信息。
为了给出一个关于这个需求的想法(即使你只对一个端口感兴趣,所有东西都必须从顶部开始枚举),下面是代码中enum.c文件顶部列出的注释:
/* This source file contains the routines which enumerate the USB bus and populate the TreeView control. The enumeration process goes like this: (1) Enumerate Host Controllers and Root Hubs EnumerateHostControllers() EnumerateHostController() Host controllers currently have symbolic link names of the form HCDx, where x starts at 0. Use CreateFile() to open each host controller symbolic link. Create a node in the TreeView to represent each host controller. GetRootHubName() After a host controller has been opened, send the host controller an IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of the root hub that is part of the host controller. (2) Enumerate Hubs (Root Hubs and External Hubs) EnumerateHub() Given the name of a hub, use CreateFile() to map the hub. Send the hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the hub, such as the number of downstream ports. Create a node in the TreeView to represent each hub. (3) Enumerate Downstream Ports EnumerateHubPorts() Given an handle to an open hub and the number of downstream ports on the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX request for each downstream port of the hub to get info about the device (if any) attached to each port. If there is a device attached to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request to get the symbolic link name of the hub attached to the downstream port. If there is a hub attached to the downstream port, recurse to step (2). GetAllStringDescriptors() GetConfigDescriptor() Create a node in the TreeView to represent each hub port and attached device. */
你尝试过SetupDi吗? 您可以使用SetupDi类的API函数从DeviceManager获取信息。
设备管理器下的“位置信息”与您通过WMI获取的字符串完全相同。
你有没有考虑过,当设备插入不同的端口,而不是用新的位置更新元数据,Windows创建一个新的驱动程序实例和新的元数据。 尝试过滤Win32_PnPDevice
对象实例,仅用于当前插入的实例,我想您会找到当前的位置信息。
例如,如果我将USB鼠标移动到不同的端口,则设备管理器下面仍旧列出与旧端口关联的鼠标副本,默认情况下它是隐藏的。 有关说明,请参阅http://oreilly.com/pub/h/3105查看这些断开连接的设备。 或者从提升的管理员命令提示符处运行以下命令:
C:\Windows\system32>set devmgr_show_nonpresent_devices=1 C:\Windows\system32>devmgmt
尽我所知,Windows中不可能将USB设备与物理端口相关联。 请随时证明我错了。
更好的方法是使用USB设备的唯一序列号。