2011-06-20 17 views
9

Mam urządzenie USB, które wylicza z innym interfejsem, VID, PID i numerem seryjnym, gdy otrzyma do tego polecenie, i chciałbym śledzić fizyczne urządzenie po tej zmianie. Moją myślą było śledzić to przez jego położenie hubu i portu.Czy fizyczny port USB można zidentyfikować programowo dla urządzenia w systemie Windows?

Klasa Win32_PnPSignedDriver ma pole "Lokalizacja", które wydawało się idealne (np. Port_#0001.Hub_#0010), ale zawiera tylko lokalizację urządzenia po załadowaniu sterownika. Podłączenie sprzętu do innego portu nie aktualizuje tego pola.

Jednak informacje są dostępne gdzieś, ponieważ pole "Informacje o lokalizacji" znajduje się w zakładce "Szczegóły" podczas przeglądania urządzenia za pomocą Menedżera urządzeń. Czy te informacje można odzyskać za pomocą WMI queries lub innej metody? Czy istnieje lepsze podejście do rozwiązania tego problemu?

EDYCJA: Wiem, że to brzmi jak dziwny scenariusz. Mikrokontroler w tych urządzeniach zawiera pamięć ROM, która wylicza jako urządzenie CDC (tj. Port szeregowy) i umożliwia programowanie. Podczas produkcji korzystne byłoby śledzenie urządzenia zmieniającego się pomiędzy ROM producenta (unikalny numer VID/PID/numer seryjny) a moim niestandardowym interfejsem oprogramowania (inny numer VID/PID/numer seryjny).

+0

wygląda jak mogę uzyskać lokalizację z rejestru poprzez 'HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB'. Napiszę odpowiedź, gdy ją zweryfikuję. –

+0

Można by się spodziewać, że ponieważ interfejs API nie-WMI ma nazwę ['SetupDiGetDeviceRegistryProperty'] (http://msdn.microsoft.com/en-us/library/ff551967.aspx) –

+0

Wygląda jak informacja o lokalizacji w kluczu HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB nie jest aktualizowany, gdy urządzenie jest podłączone do innego portu – Derek

Odpowiedz

0

Jak najlepiej jak mogę powiedzieć, korelowanie urządzenia USB z portem fizycznym nie jest możliwe w systemie Windows. Proszę, udowodnij mi, że się mylę.

+0

Czy sprawdziłeś interfejsy API Menedżera konfiguracji? ('CM_foo_bar') Jeśli menedżer urządzeń zrobi to, to musi być możliwe ... – Mehrdad

-3

Lepszym pomysłem będzie użycie unikalnego numeru seryjnego urządzenia USB.

+0

Po pierwsze, w jaki sposób uzyskać "Unikalny numer seryjny?" Po drugie, nie sądzę, że to zadziała w tym przypadku. Urządzenie niekoniecznie zachowa ten sam numer seryjny. –

+0

Przepraszam, jeśli komentarz był niegrzeczny. Pisałem to w pośpiechu, ponieważ jestem pewien, że musiałaś to zrobić. Urządzenie ma numer seryjny, ale VID, PID i numer seryjny ulegną zmianie i muszę monitorować fizyczne urządzenie, gdy tak się stanie. –

+3

Z perspektywy czasu, nie sądzę, że mój komentarz był w ogóle niegrzeczny. Nadal nie wiem, jak uzyskać numer seryjny USB z urządzenia. To jest poprawne pytanie. Tak, wszystkie urządzenia USB mają je, ale nie znam trywialnego sposobu na odzyskanie go w systemie Windows. –

2

Czy próbowałeś SetupDi? Możesz użyć funkcji API klasy SetupDi, aby pobrać informacje z DeviceManager.

+0

Jestem zaznajomiony z SetupDi, ale liczył na rozwiązanie WMI, aby uniknąć czynienia z DDK i PInvoke. –

+0

Czy istnieje określony interfejs SetupDi, który ujawnia te informacje, o których jesteś świadomy? –

+1

Myślę, że będziesz musiał zadzwonić do kilku API SetupDi, aby uzyskać te informacje. za. Wymień dostępne urządzenia dla konkretnej klasy Urządzenia (klasa urządzeń USB w twoim przypadku). Wylicz przy użyciu metody SetupDiGetClassDevs. Następnie wykonaj iterację w tej kolekcji, korzystając z API SetupDiEnumDeviceInfo, a następnie dla każdego urządzenia pobierz odpowiednią właściwość urządzenia, korzystając z interfejsu API SetupDiGetDeviceRegistryProperty. Wyliczenie właściwości rejestru jest dostępne pod adresem http://www.pinvoke.net/default.aspx/Enums/SPDRP%20.html –

1

"Informacje o lokalizacji" w Menedżerze urządzeń to dokładnie ten sam ciąg, który przeszedłeś przez WMI.

Czy uważasz, że gdy urządzenie jest podłączone do innego portu, zamiast aktualizować metadane z nową lokalizacją, system Windows tworzy nową instancję sterownika i nowe metadane. Spróbuj filtrować instancje obiektów Win32_PnPDevice tylko dla tych, które są obecnie podłączone i myślę, że znajdziesz aktualne informacje o lokalizacji.

Na przykład, jeśli przeniosę mysz USB na inny port, znajduje się kopia myszy powiązanej ze starym portem nadal wyświetlanym w Menedżerze urządzeń, domyślnie jest ukryta. Instrukcje dotyczące wyświetlania tych odłączonych urządzeń można znaleźć w sekcji http://oreilly.com/pub/h/3105. Lub uruchom następujące polecenia z wiersza polecenia administratora:

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

Nowe wystąpienia Win32_PnPSignedDriver nie są tworzone, gdy korzystam z innego portu USB. Ładuje ten sam sterownik i nie aktualizuje lokalizacji. –

+0

Interesujący temat. @Judge: Czy powyższy komentarz może być spowodowany przez porty USB znajdujące się w tym samym hoście USB? Jestem tutaj bardzo nie w moim żywiole, ale uważam, że temat jest bardzo interesujący. – jp2code

+0

@Judge: 'Win32_PnPSignedDriver' i tak ci nie pomoże, ponieważ może istnieć wiele instancji urządzenia używających tego samego sterownika. –

8

Wiem, że upłynęło trochę czasu, odkąd podjęto jakiekolwiek działania w związku z tą odpowiedzią, ale pracuję nad projektem, który również wymaga podobnej funkcjonalności, i mogę powiedzieć, że jest to rzeczywiście możliwe. O ile mogę powiedzieć, wymaga DDK i PInvoke, nie ma interfejsu C# lub WMI dla tych informacji. Wymaga to otwarcia niskiego poziomu koncentratorów USB USB i bezpośredniego wysyłania do nich poleceń IOCTL sterownika.

Dobra wiadomość jest taka, że ​​Microsoft dostarcza przykładową aplikację C++, która całkowicie wylicza wszystkie urządzenia USB i pokazuje dokładnie, do których portów są podłączone. Ta aplikacja to USBView sample application.

Myślę, że znajdziesz, jeśli skompilujesz i uruchomisz tę aplikację, zobaczysz, że pokazuje dokładnie, gdzie jest podłączone urządzenie, a jeśli podłączysz dowolne urządzenie do tego portu, pojawi się w tym samym miejscu .Być może może być łatwiejsze, jeśli utworzysz niezarządzaną bibliotekę DLL w C++, która zapewnia kilka wywołań, z których może korzystać aplikacja C# do uzyskania potrzebnych informacji.

on ma do powiedzenia o „EnumerateHubPorts()” funkcja w to kod:

Biorąc pod uwagę uchwyt do otwartej piasty oraz liczby portów downstream na piasta, wyślij piastę IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX żądanie dla każdego dalszego portu w hoście, aby uzyskać informacje o urządzeniu (jeśli jest) podłączonym do każdego portu.

Aby dać wyobrażenie o wszystkim wymaga to (wszystko musi być numerowane, zaczynając od góry, nawet jeśli jesteś zainteresowany tylko w jednym porcie) Oto komentarze wymienione na początku pliku enum.c w kodzie:

/* 

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

Rozwiązałem problem, który miałem, ale na pewno się na to przyjrzę. Dzięki! –

Powiązane problemy