2011-06-20 50 views
9

Tôi có một thiết bị USB liệt kê với một giao diện khác, VID, PID và số sê-ri khi được lệnh thực hiện, và tôi muốn theo dõi thiết bị vật lý sau khi thay đổi này xảy ra. Suy nghĩ của tôi là theo dõi nó bằng vị trí trung tâm và cảng của nó.Cổng USB vật lý có thể được xác định theo chương trình cho một thiết bị trong Windows không?

Lớp Win32_PnPSignedDriver có trường "Vị trí" có vẻ hoàn hảo (ví dụ: Port_#0001.Hub_#0010), nhưng nó chỉ chứa vị trí của thiết bị khi trình điều khiển được tải lần đầu tiên. Cắm phần cứng vào một cổng khác không cập nhật trường đó.

Tuy nhiên, thông tin có sẵn ở đâu đó vì có trường "Thông tin vị trí" trong tab "Chi tiết" khi xem thiết bị thông qua Trình quản lý thiết bị. Thông tin này có thể được truy xuất thông qua WMI queries hoặc một số phương pháp khác không? Có cách nào tốt hơn để giải quyết vấn đề này?

EDIT: Tôi biết điều này nghe có vẻ giống như một trường hợp lạ. Bộ vi điều khiển trong các thiết bị này chứa một ROM liệt kê như một thiết bị CDC (tức là cổng nối tiếp) và cho phép lập trình. Trong quá trình sản xuất, sẽ có ích khi theo dõi một thiết bị vì nó thay đổi giữa ROM của nhà sản xuất (số VID/PID/số duy nhất) và giao diện phần mềm tùy chỉnh của tôi (số VID/PID/serial khác nhau).

+0

Dường như tôi có thể lấy vị trí từ sổ đăng ký qua 'HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB'. Tôi sẽ viết một câu trả lời khi tôi xác minh nó. –

+0

Người ta có thể mong đợi rằng, vì API không phải WMI được đặt tên ['SetupDiGetDeviceRegistryProperty'] (http://msdn.microsoft.com/en-us/library/ff551967.aspx) –

+0

Trông giống như LocationInformation trong HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ USB không được cập nhật khi thiết bị được cắm vào một cổng khác hoặc – Derek

Trả lời

0

Tốt nhất có thể, tương quan với thiết bị USB có cổng vật lý là không thể trong Windows. Xin vui lòng chứng minh cho tôi sai.

+0

Bạn có nhìn vào API Trình quản lý cấu hình không? ('CM_foo_bar') Nếu trình quản lý thiết bị thực hiện điều này thì nó phải có thể ... – Mehrdad

-3

Ý tưởng hay hơn là sử dụng số sê-ri duy nhất của thiết bị USB.

+0

Trước tiên, làm cách nào để nhận được "Số sêri duy nhất?" Thứ hai, tôi không nghĩ rằng sẽ làm việc trong trường hợp này. Thiết bị sẽ không nhất thiết phải giữ lại cùng một số sê-ri. –

+0

Tôi xin lỗi nếu nhận xét đó có vẻ thô lỗ. Tôi đã gõ nó một cách nhanh chóng như tôi chắc chắn bạn phải đã làm là tốt. Thiết bị có một số sê-ri, nhưng VID, PID và số sê-ri sẽ thay đổi và tôi cần phải theo dõi thiết bị vật lý khi điều này xảy ra. –

+3

Nhìn lại, tôi không nghĩ rằng bình luận của tôi là thô lỗ chút nào. Tôi vẫn không biết cách lấy số sê-ri USB từ thiết bị. Đó là một câu hỏi hợp lệ. Có, tất cả các thiết bị USB có chúng, nhưng tôi không biết một cách tầm thường để lấy nó trong Windows. –

2

Bạn đã thử SetupDi chưa? Bạn có thể sử dụng chức năng API lớp SetupDi để lấy thông tin từ DeviceManager.

+0

Tôi quen thuộc với SetupDi, nhưng đã hy vọng cho một giải pháp WMI để tránh đối phó với DDK và PInvoke. –

+0

Có giao diện SetupDi cụ thể nào cho thấy thông tin mà bạn biết không? –

+1

Tôi nghĩ bạn sẽ cần phải gọi một vài API SetupDi để nhận thông tin này. a. Liệt kê các thiết bị có sẵn cho một lớp Device cụ thể (lớp thiết bị USB trong trường hợp của bạn). Liệt kê sử dụng phương thức SetupDiGetClassDevs. Sau đó lặp qua bộ sưu tập này bằng cách sử dụng API SetupDiEnumDeviceInfo và sau đó cho mỗi thiết bị này nhận được thuộc tính thiết bị có liên quan bằng cách sử dụng API SetupDiGetDeviceRegistryProperty. Thuộc tính đăng ký enum có sẵn tại http://www.pinvoke.net/default.aspx/Enums/SPDRP%20.html –

1

"Thông tin vị trí" trong trình quản lý thiết bị là chuỗi chính xác mà bạn đã nhận được thông qua WMI.

Bạn đã cân nhắc khi thiết bị được cắm vào một cổng khác, thay vì cập nhật siêu dữ liệu với vị trí mới, Windows sẽ tạo một phiên bản trình điều khiển mới và siêu dữ liệu mới. Thử lọc các trường hợp đối tượng Win32_PnPDevice chỉ cho những trường hợp hiện đang được cắm vào và tôi nghĩ bạn sẽ tìm thấy thông tin vị trí hiện tại.

Ví dụ, nếu tôi di chuyển chuột USB của mình sang một cổng khác, có một bản sao của chuột được kết hợp với cổng cũ vẫn được liệt kê trong Trình quản lý thiết bị, nó chỉ bị ẩn theo mặc định. Xem http://oreilly.com/pub/h/3105 để biết hướng dẫn xem các thiết bị đã ngắt kết nối này. Hoặc chạy phần sau từ lời nhắc lệnh quản trị viên nâng cao:

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

Phiên bản mới của Win32_PnPSignedDriver không được tạo khi tôi sử dụng cổng USB khác. Nó tải cùng một trình điều khiển và không cập nhật vị trí. –

+0

Chủ đề thú vị. @Judge: Có thể nhận xét của bạn ở trên được gây ra bởi các cổng USB nằm trên cùng một hub USB không? Tôi rất yếu tố của tôi ở đây, nhưng tôi thấy chủ đề rất thú vị. – jp2code

+0

@Judge: 'Win32_PnPSignedDriver' sẽ không giúp bạn dù sao, vì có thể có nhiều phiên bản thiết bị sử dụng cùng một trình điều khiển. –

8

Tôi biết đã lâu rồi kể từ khi có bất kỳ hoạt động nào trong câu trả lời này, nhưng tôi đang làm việc trên một dự án yêu cầu một chức năng tương tự như vậy, và tôi có thể nói với bạn rằng điều đó thực sự có thể. Theo như tôi có thể nói, nó đòi hỏi DDK và PInvoke, không có giao diện C# hoặc WMI cho thông tin này. Nó yêu cầu mở các thiết bị trung tâm gốc USB cấp thấp và gửi trực tiếp các lệnh IOCTL của trình điều khiển tới chúng.

Tin tốt là, Microsoft cung cấp ứng dụng ví dụ C++ liệt kê hoàn toàn tất cả các thiết bị USB và hiển thị chính xác cổng nào được kết nối. Ứng dụng đó là USBView sample application.

Tôi nghĩ bạn sẽ tìm thấy nếu bạn biên dịch và chạy ứng dụng này, bạn sẽ thấy nó cho bạn thấy chính xác vị trí thiết bị của bạn được cắm vào, và nếu bạn cắm bất kỳ thiết bị nào vào cổng đó, nó sẽ xuất hiện ở cùng một nơi .Có lẽ nó có thể dễ dàng hơn nếu bạn tạo một C++ DLL không được quản lý cung cấp một vài cuộc gọi mà ứng dụng C# của bạn có thể sử dụng để lấy thông tin cần thiết.

Nó có này để nói về "EnumerateHubPorts()" chức năng trong nó là mã:

Với một tay cầm một hub mở và số lượng cổng hạ lưu trên trung tâm, gửi trung tâm một IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX Yêu cầu cho mỗi cổng hạ lưu của trung tâm để nhận thông tin về thiết bị (nếu có) được gắn vào mỗi cổng.

Để đưa ra ý tưởng về mọi thứ yêu cầu (mọi thứ phải được liệt kê bắt đầu ở trên cùng, ngay cả khi bạn chỉ quan tâm đến một cổng), dưới đây là các nhận xét được liệt kê ở đầu tệp enum.c trong mã:

/* 

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

Tôi đã giải quyết vấn đề mà tôi có, nhưng tôi chắc chắn sẽ xem xét vấn đề này. Cảm ơn! –

Các vấn đề liên quan