Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以通过编程方式为Windows中的设备标识物理USB端口?_C#_Windows_Usb_Wmi_Wmi Query - Fatal编程技术网

C# 是否可以通过编程方式为Windows中的设备标识物理USB端口?

C# 是否可以通过编程方式为Windows中的设备标识物理USB端口?,c#,windows,usb,wmi,wmi-query,C#,Windows,Usb,Wmi,Wmi Query,我有一个USB设备,当被命令这样做时,它使用不同的接口、VID、PID和序列号进行枚举,我希望在发生此更改后跟踪物理设备。我的想法是通过它的枢纽和港口位置来跟踪它 该类有一个看似完美的“位置”字段(例如,Port_35;0001.Hub_35;0010),但它只包含首次加载驱动程序时设备的位置。将硬件插入其他端口不会更新该字段 但是,由于通过设备管理器查看设备时,在“详细信息”选项卡下有一个“位置信息”字段,因此该信息在某个位置可用。该信息可以通过或其他方法检索吗?有没有更好的方法来解决这个问题

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

该类有一个看似完美的“位置”字段(例如,
Port_35;0001.Hub_35;0010
),但它只包含首次加载驱动程序时设备的位置。将硬件插入其他端口不会更新该字段

但是,由于通过设备管理器查看设备时,在“详细信息”选项卡下有一个“位置信息”字段,因此该信息在某个位置可用。该信息可以通过或其他方法检索吗?有没有更好的方法来解决这个问题


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

更好的办法是使用USB设备的唯一序列号。

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

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

您是否考虑过,当设备插入其他端口时,Windows会创建新的驱动程序实例和新的元数据,而不是使用新位置更新元数据。请尝试筛选
Win32\u PnPDevice
对象实例,以查找当前插入的实例,我想您会找到当前位置信息

例如,如果我将USB鼠标移动到另一个端口,则在设备管理器下仍会列出与旧端口关联的鼠标副本,默认情况下,它只是隐藏的。有关查看这些断开连接的设备的说明,请参阅。或从提升的管理员命令提示符运行以下命令:

C:\Windows\system32>set devmgr_show_nonpresent_devices=1
C:\Windows\system32>devmgmt

据我所知,将USB设备与物理端口关联在Windows中是不可能的。请随时证明我是错的。

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

<> Po>好消息是,微软提供了一个完全列举所有USB设备并准确显示它们连接到哪个端口的C++应用程序的例子。该应用程序是最新的

我想你会发现,如果你编译并运行这个应用程序,你会看到它准确地显示了你的设备插入的位置,如果你将任何设备插入该端口,它会显示在相同的位置。如果创建一个非托管C++ DLL,也许可以更容易地提供一些调用,C语言应用程序可以用来获取它需要的信息。 它的代码中有
EnumerateHubPorts()
函数:

给定开放集线器的句柄和集线器上的下游端口数 集线器,向集线器发送IOCTL\u USB\u GET\u NODE\u CONNECTION\u INFORMATION\u 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.
*/
REF:“Win32_PnPSignedDriver类有一个看似完美的“位置”字段(例如Port#0001.Hub#0010),但它只包含第一次加载驱动程序时设备的位置。将硬件插入其他端口不会更新该字段。”

对我来说是的。但是,请确保在端口交换之间刷新(F5)regedit应用程序,否则您将看不到更改

以下是一些例子:





首先,我如何获得“唯一序列号?”其次,我认为这在这种情况下不起作用。设备不一定会保留相同的序列号。如果评论被认为粗鲁,我道歉。我打字很匆忙,我相信你也一定打得很好。设备有一个序列号,但VID、PID和序列号将发生变化,发生这种情况时,我需要跟踪物理设备。回想起来,我认为我的评论一点也不粗鲁。我仍然不知道如何从设备中检索USB序列号。这是一个合理的问题。是的,所有USB设备都有,但我不知道在Windows中检索它的简单方法。@法官:如果您决定使用序列号,请尝试。但是,如果您的重新枚举(固件更新?)随VID/PID一起更改序列号,则不会有任何帮助。当我使用其他USB端口时,不会创建Win32\u PnPSignedDriver的新实例。它加载相同的驱动程序并且不更新位置。有趣的主题@法官:你上面的评论是不是由同一个USB集线器上的USB端口引起的?我对这里的内容很不熟悉,但我觉得这个主题很有趣。@Judge:
Win32\u PnPSignedDriver
对您没有任何帮助,因为可能有许多设备实例使用同一个驱动程序。@Ben好的,这很有意义。谢谢。我熟悉SetupDi,但希望有一个WMI解决方案来避免处理DDK和PInvoke。是否有一个特定的SetupDi接口公开了您知道的这些信息?我想您需要调用一些SetupDi API来获取此信息