2011-06-20 31 views
9

我有一個USB設備,在命令時使用不同的接口,VID,PID和序列號進行枚舉,並且我希望在發生此更改後跟蹤物理設備。我的想法是通過它的樞紐和港口位置來追蹤它。可以通過編程方式爲Windows中的設備識別物理USB端口嗎?

Win32_PnPSignedDriver類有一個看起來很完美的「位置」字段(例如Port_#0001.Hub_#0010),但它只包含驅動程序第一次加載時設備的位置。將硬件插入其他端口不會更新該字段。

但是,信息在某處可用,因爲在通過設備管理器查看設備時,「詳細信息」選項卡下有一個「位置信息」字段。可以通過WMI queries或其他方法檢索這些信息嗎?有沒有更好的方法來解決這個問題?

編輯:我知道這聽起來像一個奇怪的場景。這些器件中的微控制器包含一個枚舉爲CDC器件(即串行端口)並允許編程的ROM。在製造過程中,跟蹤製造商的ROM(唯一的VID/PID /序列號)和我的定製固件接口(不同的VID/PID /序列號)之間的設備變化是非常有益的。

+0

它看起來像我可以通過'HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB'從註冊表獲取位置。一旦我確認了,我會寫一個答案。 –

+0

可以預料到,因爲非WMI API被命名爲['SetupDiGetDeviceRegistryProperty'](http://msdn.microsoft.com/en-us/library/ff551967.aspx) –

+0

看起來像位於HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB在設備插入不同的端口時不會更新 – Derek

回答

0

盡我所知,在Windows中無法將USB設備與物理端口相關聯。請隨時證明我錯了。

+0

您是否看過Configuration Manager API? ('CM_foo_bar')如果設備管理器這樣做,那麼它必須是可能的... – Mehrdad

-3

更好的主意是使用USB設備的唯一序列號。

+0

首先,我如何獲得「唯一序列號?」其次,我認爲這不適用於這種情況。該設備不一定會保留相同的序列號。 –

+0

我很抱歉,如果評論意見粗暴。我匆匆打字,因爲我相信你一定也做得很好。該設備有一個序列號,但VID,PID和序列號會改變,我需要在發生這種情況時跟蹤物理設備。 –

+3

回想起來,我認爲我的評論根本不算粗魯。我仍然不知道如何從設備中檢索USB序列號。這是一個有效的問題。是的,所有的USB設備都有它們,但我不知道在Windows中檢索它的方法。 –

2

您是否嘗試過SetupDi? 您可以使用SetupDi類的API函數從DeviceManager獲取信息。

+0

我對SetupDi很熟悉,但希望有一個WMI解決方案來避免處理DDK和PInvoke。 –

+0

是否有一個特定的SetupDi接口公開了您所知道的這些信息? –

+1

我想你需要調用一些SetupDi API來獲取這些信息。一個。枚舉特定設備類的可用設備(在您的情況下爲USB設備類)。枚舉使用SetupDiGetClassDevs方法。然後使用SetupDiEnumDeviceInfo API迭代該集合,然後通過使用SetupDiGetDeviceRegistryProperty API獲取相關設備屬性。註冊表屬性枚舉位於http://www.pinvoke.net/default.aspx/Enums/SPDRP%20.html –

1

設備管理器下的「位置信息」與您通過WMI獲取的字符串完全相同。

您是否認爲,當設備插入到不同的端口中時,Windows將創建新的驅動程序實例和新的元數據,而不是使用新位置更新元數據。嘗試過濾僅用於當前插入的對象實例的Win32_PnPDevice對象實例,我想您會找到當前的位置信息。

例如,如果我將USB鼠標移動到不同的端口,那麼在設備管理器下仍然會列出與舊端口關聯的鼠標副本,它只是默認隱藏。請參閱http://oreilly.com/pub/h/3105以獲取查看這些斷開設備的說明。或者從提升的管理員命令提示符處運行以下命令:

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

當我使用不同的USB端口時,不會創建Win32_PnPSignedDriver的新實例。它加載相同的驅動程序並且不更新位置。 –

+0

有趣的話題。 @Judge:您的評論可能是由同一USB集線器上的USB端口引起的嗎?我非常喜歡這裏,但我覺得這個話題非常有趣。 – jp2code

+0

@Judge:'Win32_PnPSignedDriver'無論如何不會幫助你,因爲可以有許多設備實例使用相同的驅動程序。 –

8

我知道這個答案已經有一段時間了,但我正在研究一個需要類似功能的項目,我可以告訴你這確實是可能的。據我所知,它確實需要DDK和PInvoke,這個信息沒有C#或WMI接口。它需要打開低級USB根集線器設備並直接向它們發送驅動程序IOCTL命令。

好消息是,微軟提供了一個示例C++應用程序,它可以完全枚舉所有USB設備,並準確顯示它們連接的端口。該應用程序是USBView sample application

我想你會發現,如果你編譯並運行這個應用程序,你會發現它確實顯示了你的設備插入的位置,如果你插入任何設備到該端口,它顯示在同一個地方。如果你創建一個非託管的C++ DLL,它可以提供一些C#應用程序可以用來獲取所需信息的調用。

它有這樣說的「EnumerateHubPorts()」中的IT部門代碼:

給出一個手柄,一個開放的樞紐和下游端口上 樞紐的數量,送樞紐的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. 
*/ 
+0

我曾經解決過我遇到的問題,但我一定會看看這個。謝謝! –

相關問題