首页 文章

是否可以以编程方式为Windows中的设备识别物理USB端口?

提问于
浏览
10

我有一个USB设备,在命令时使用不同的接口,VID,PID和序列号进行枚举,并且我想在发生此更改后跟踪物理设备 . 我的想法是通过它的枢纽和港口位置来跟踪它 .

Win32_PnPSignedDriver类的"Location"字段看起来很完美(例如 Port_#0001.Hub_#0010 ),但它只包含首次加载驱动程序时设备的位置 . 将硬件插入不同的端口不会更新该字段 .

但是,由于在通过“设备管理器”查看设备时"Details"选项卡下有"Location information"字段,因此可以在某处获得该信息 . 可以通过WMI queries或其他方法检索此信息吗?有没有更好的方法来解决这个问题?

EDIT: 我知道这听起来像是一个奇怪的场景 . 这些设备中的微控制器包含一个ROM,该ROM枚举为CDC设备(即串行端口)并允许编程 . 在制造过程中,跟踪设备,因为它在制造商的ROM(唯一的VID / PID /序列号)和我的自定义固件接口(不同的VID / PID /序列号)之间变化是有益的 .

5 回答

  • 2

    我知道自从这个答案的任何活动以来已经有一段时间了,但是我正在开发一个需要类似功能的项目,我可以告诉你它确实是可能的 . 据我所知,它确实需要DDK和PInvoke,这个信息没有C#或WMI接口 . 它需要打开低级USB根集线器设备并直接向它们发送驱动程序IOCTL命令 .

    好消息是,Microsoft提供了一个示例C应用程序,它完全枚举所有USB设备并准确显示它们所连接的端口 . 该应用程序是USBView sample application .

    我想你会发现如果你编译并运行这个应用程序,你会发现它确切地显示了你的设备插入的位置,如果你将任何设备插入该端口,它会显示在同一个地方 . 如果你创建一个非托管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.
    */
    
  • -1

    你尝试过SetupDi吗?您可以使用SetupDi类API函数从DeviceManager获取信息 .

  • 8

    设备管理器下的“位置信息”与您通过WMI获得的字符串完全相同 .

    您是否考虑过将设备插入其他端口时,而不是使用新位置更新元数据,Windows会创建新的驱动程序实例和新元数据 . 尝试过滤 Win32_PnPDevice 对象实例,只为那些当前插入的对象实例,我想你会找到当前的位置信息 .

    例如,如果我将USB鼠标移动到其他端口,则默认情况下会隐藏's a copy of the mouse associated with the old port still listed under Device Manager, it' . 有关查看这些断开连接的设备的说明,请参见http://oreilly.com/pub/h/3105 . 或者从提升的管理员命令提示符运行以下命令:

    C:\Windows\system32>set devmgr_show_nonpresent_devices=1
    C:\Windows\system32>devmgmt
    
  • -3

    据我所知,在Windows中无法将USB设备与物理端口相关联 . 请随意证明我的错 .

  • 2

    更好的想法是使用USB设备的唯一序列号 .

相关问题