2010-07-25 68 views

Trả lời

87

Thêm một tham chiếu đến System.Management cho dự án của bạn, sau đó thử một cái gì đó như thế này:

namespace ConsoleApplication1 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Management; // need to add System.Management to your project references. 

    class Program 
    { 
    static void Main(string[] args) 
    { 
     var usbDevices = GetUSBDevices(); 

     foreach (var usbDevice in usbDevices) 
     { 
     Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}", 
      usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description); 
     } 

     Console.Read(); 
    } 

    static List<USBDeviceInfo> GetUSBDevices() 
    { 
     List<USBDeviceInfo> devices = new List<USBDeviceInfo>(); 

     ManagementObjectCollection collection; 
     using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub")) 
     collection = searcher.Get();  

     foreach (var device in collection) 
     { 
     devices.Add(new USBDeviceInfo(
     (string)device.GetPropertyValue("DeviceID"), 
     (string)device.GetPropertyValue("PNPDeviceID"), 
     (string)device.GetPropertyValue("Description") 
     )); 
     } 

     collection.Dispose(); 
     return devices; 
    } 
    } 

    class USBDeviceInfo 
    { 
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description) 
    { 
     this.DeviceID = deviceID; 
     this.PnpDeviceID = pnpDeviceID; 
     this.Description = description; 
    } 
    public string DeviceID { get; private set; } 
    public string PnpDeviceID { get; private set; } 
    public string Description { get; private set; } 
    } 
} 
+12

Có cách nào để lấy tên thân thiện của thiết bị không? Ví dụ khi tôi đi vào các thuộc tính của thanh usb của tôi, tôi thấy "Thiết bị USB DataTraveler 2.0 của Kingston". – Robert

+1

Sự khác biệt giữa DeviceID và PNPDeviceID là gì? – Shimmy

+1

Khi tôi chạy chương trình trên, tôi nhận được đĩa cứng USB, bàn phím và chuột, nhưng tôi không nhận được máy ảnh USB, USB A/D của mình. Tại sao tất cả các thiết bị USB của tôi không hiển thị? – Curt

2

Bạn có thể tìm thấy this thread hữu ích. Và đây là số google code project minh họa điều này (nó P/Gọi vào setupapi.dll).

+0

Bạn có biết tại sao lớp ObjectQuery không có tham chiếu mặc dù tôi đang sử dụng System.Management không? – Robert

+0

@Robert bạn đã thêm tham chiếu vào dự án chưa? Bạn có thể thực hiện việc này bằng cách nhấp chuột phải vào Tham chiếu trong dự án của bạn> Thêm tham chiếu ...> Tìm kiếm và kiểm tra System.Management> OK. – Ernest

9

Để xem các thiết bị tôi đã quan tâm, tôi đã thay thế Win32_USBHub bởi Win32_PnPEntity trong mã Adel Hazzah của, dựa trên this post. Này làm việc cho tôi:

namespace ConsoleApplication1 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Management; // need to add System.Management to your project references. 

    class Program 
    { 
    static void Main(string[] args) 
    { 
     var usbDevices = GetUSBDevices(); 

     foreach (var usbDevice in usbDevices) 
     { 
     Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}", 
      usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description); 
     } 

     Console.Read(); 
    } 

    static List<USBDeviceInfo> GetUSBDevices() 
    { 
     List<USBDeviceInfo> devices = new List<USBDeviceInfo>(); 

     ManagementObjectCollection collection; 
     using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity")) 
     collection = searcher.Get();  

     foreach (var device in collection) 
     { 
     devices.Add(new USBDeviceInfo(
     (string)device.GetPropertyValue("DeviceID"), 
     (string)device.GetPropertyValue("PNPDeviceID"), 
     (string)device.GetPropertyValue("Description") 
     )); 
     } 

     collection.Dispose(); 
     return devices; 
    } 
    } 

    class USBDeviceInfo 
    { 
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description) 
    { 
     this.DeviceID = deviceID; 
     this.PnpDeviceID = pnpDeviceID; 
     this.Description = description; 
    } 
    public string DeviceID { get; private set; } 
    public string PnpDeviceID { get; private set; } 
    public string Description { get; private set; } 
    } 
} 
3

Nếu bạn thay đổi ManagementObjectSearcher như sau:

ManagementObjectSearcher searcher = 
     new ManagementObjectSearcher("root\\CIMV2", 
     @"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""); 

Vì vậy, các "GetUSBDevices() trông như thế này"

static List<USBDeviceInfo> GetUSBDevices() 
{ 
    List<USBDeviceInfo> devices = new List<USBDeviceInfo>(); 

    ManagementObjectCollection collection; 
    using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""")) 
    collection = searcher.Get();  

    foreach (var device in collection) 
    { 
    devices.Add(new USBDeviceInfo(
    (string)device.GetPropertyValue("DeviceID"), 
    (string)device.GetPropertyValue("PNPDeviceID"), 
    (string)device.GetPropertyValue("Description") 
    )); 
    } 

    collection.Dispose(); 
    return devices; 
} 

}

Kết quả của bạn sẽ bị giới hạn đối với các thiết bị USB (trái ngược với tất cả các loại trên hệ thống của bạn)

+0

Điều khoản where tìm kiếm deviceID bắt đầu bằng USB bỏ sót một số mục. Nó tốt hơn để lặp lại những người phụ thuộc của "Win32_USBControllerDevice" –

22

Tôi biết tôi đang trả lời một câu hỏi cũ, nhưng tôi vừa trải qua bài tập này và tìm hiểu thêm một chút thông tin, tôi nghĩ sẽ đóng góp rất nhiều cho cuộc thảo luận và giúp đỡ bất kỳ ai khác tìm thấy câu hỏi này và xem vị trí các câu trả lời hiện tại sẽ ngắn.

accepted answer đóng và có thể sửa được bằng cách sử dụng Nedko's comment. Một sự hiểu biết chi tiết hơn về các lớp WMI có liên quan giúp hoàn thành bức tranh.

Win32_USBHub chỉ trả về USB Hubs. Điều đó có vẻ hiển nhiên trong việc nhận thức nhưng các cuộc thảo luận ở trên đã bỏ qua nó. Nó không bao gồm tất cả các thiết bị USB có thể, chỉ những thiết bị có thể (theo lý thuyết, ít nhất) hoạt động như một trung tâm cho các thiết bị bổ sung. Nó bỏ lỡ một số thiết bị không phải là hub (đặc biệt là các bộ phận của thiết bị tổng hợp).

Win32_PnPEntity không bao gồm tất cả thiết bị USB và hàng trăm thiết bị không phải USB. Russel Gantman's lời khuyên để sử dụng tìm kiếm khoản WHERE Win32_PnPEntity cho DeviceID bắt đầu bằng "USB%" để lọc danh sách hữu ích nhưng không đầy đủ; nó nhớ những con chuột và bàn phím tương thích với HID. Tôi tin rằng "USB \%", "USBSTOR \%", "USBPRINT \%" và "HID \%" sẽ liệt kê hoàn toàn tất cả các khả năng, nhưng vì có các tùy chọn tốt hơn, điều này có thể không cần thiết để theo đuổi. Tuy nhiên, Win32_PnPEntity là tài liệu tham khảo "chính" tốt để tra cứu thông tin khi bạn sở hữu PNPDeviceID từ các nguồn khác.

Điều tôi thấy là cách tốt nhất để liệt kê thiết bị USB là truy vấn Win32_USBControllerDevice. Trong khi nó không cung cấp thông tin chi tiết cho các thiết bị, nó liệt kê hoàn toàn các thiết bị USB của bạn và cung cấp cho bạn một cặp Antecedent/Dependent là PNPDeviceID s cho mọi thiết bị USB (bao gồm Hubs, thiết bị không phải Hub và thiết bị tương thích HID) hệ thống của bạn. Mỗi Người phụ thuộc được trả về từ truy vấn sẽ là Thiết bị USB. Tiền tố sẽ là Bộ điều khiển được gán cho nó, một trong các Bộ điều khiển USB được trả về bằng cách truy vấn Win32_USBController.

Là tiền thưởng, có vẻ như dưới mui xe, WMI đi theo số Device Tree khi trả lời truy vấn Win32_USBControllerDevice, do đó thứ tự trả về có thể giúp xác định mối quan hệ cha/con. (Đây không phải là tài liệu và do đó chỉ là một đoán, sử dụng SetupDi API của CM_Get_Parent (hoặc Child + Sibling) cho kết quả dứt khoát.) Là một tùy chọn cho API SetupDi, nó xuất hiện cho tất cả các thiết bị được liệt kê dưới Win32_USBHub chúng có thể được xem xét trong sổ đăng ký (tại HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID) và sẽ có tham số ParentIdPrefix sẽ là tiền tố của trường cuối cùng trong PNPDeviceID của các con, vì vậy điều này cũng có thể được sử dụng trong kết quả khớp ký tự đại diện để lọc truy vấn Win32_PnPEntity.

Trong ứng dụng của tôi, tôi đã làm như sau:

  • (Tùy chọn) đã truy vấn Win32_PnPEntity và lưu trữ các kết quả trong một bản đồ giá trị khóa (với PNPDeviceID là chìa khóa) để thu hồi sau. Đây là tùy chọn nếu bạn muốn thực hiện các truy vấn riêng lẻ sau này.
  • Đã truy vấn Win32_USBControllerDevice để có danh sách xác định các thiết bị USB trên hệ thống của tôi (tất cả các Phụ thuộc) và trích xuất PNPDeviceID của các thiết bị này. Tôi đã đi xa hơn, dựa trên thứ tự sau cây thiết bị, để gán các thiết bị cho hub gốc (thiết bị đầu tiên được trả về, chứ không phải bộ điều khiển) và xây dựng một cây dựa trên parentIdPrefix. Thứ tự truy vấn trả về, khớp với liệt kê cây thiết bị thông qua SetupDi, là mỗi trung tâm gốc (mà trước đó Antecedent xác định bộ điều khiển), theo sau là một sự lặp lại của các thiết bị, ví dụ: trên hệ thống của tôi:
    • Root hub của bộ điều khiển đầu tiên
    • gốc trung tâm của bộ điều khiển thứ hai
      • trung tâm đầu tiên dưới trung tâm gốc của bộ điều khiển thứ hai (có parentIdPrefix)
        • thiết bị tổng hợp đầu tiên dưới trung tâm đầu tiên dưới trung tâm gốc của bộ điều khiển thứ hai (PNPDeviceID phù hợp trên trung tâm của P arentIdPrefix; có ParentIdPrefix riêng của mình)
          • HID phần Device của thiết bị composite (PNPDeviceID phù hợp trên ParentIDPrefix thiết bị tổng hợp của)
        • thiết bị thứ hai dưới trung tâm đầu tiên dưới trung tâm gốc của bộ điều khiển thứ hai
          • HID Device phần của thiết bị tổng hợp
      • Trung tâm thứ hai dưới trung tâm gốc của secon d khiển
        • thiết bị đầu tiên dưới trung tâm thứ hai dưới hub gốc của bộ điều khiển thứ hai
      • trung tâm thứ ba dưới hub gốc của bộ điều khiển thứ hai
      • , vv
  • đã truy vấn Win32_USBController. Điều này đã cho tôi những thông tin chi tiết về các PNPDeviceID của các bộ điều khiển của tôi nằm ở phía trên cùng của cây thiết bị (đó là các Antecedents của truy vấn trước đó).Sử dụng cây có nguồn gốc từ bước trước, lặp lại đệ quy trên con của nó (trung tâm gốc) và con cái của họ (trung tâm khác) và con cái của họ (thiết bị không trung tâm và thiết bị tổng hợp) và con cái của họ, v.v.
    • Lấy chi tiết cho từng thiết bị trong cây của tôi bằng cách tham khảo bản đồ được lưu trữ trong bước đầu tiên. (Tùy chọn, người ta có thể bỏ qua bước đầu tiên, và truy vấn Win32_PnPEntity cá nhân bằng cách sử dụng PNPDeviceId để có được những thông tin ở bước này; có thể là một cpu vs bộ nhớ cân bằng xác định thứ tự nào là tốt hơn.)

Nói tóm lại , Win32USBControllerDevice Người phụ thuộc là danh sách đầy đủ các thiết bị USB trên một hệ thống (không phải là Bộ điều khiển, là tiền đề trong cùng một truy vấn đó) và bằng cách tham chiếu chéo các cặp PNPDeviceId này với thông tin từ sổ đăng ký và các truy vấn khác được đề cập, một bức tranh chi tiết có thể được xây dựng.

+0

Nếu một người có 4 máy quét giống hệt nhau được kết nối, bạn sẽ phân biệt được điều gì nếu chúng được sử dụng ở 4 hoạt động khác nhau, chẳng hạn? – topshot

+1

@topshot PNPDeviceID là duy nhất miễn là nó được kết nối. Sẽ không có cách nào để nói nếu bạn ngắt kết nối một và kết nối một thứ hai giống hệt nhau sau này. ID này cũng được tham chiếu chéo ở các khu vực khác để hy vọng xác định hoạt động nào được sử dụng. –

2

Đây là ví dụ đơn giản hơn nhiều cho những người chỉ tìm kiếm ổ đĩa USB di động.

using System.IO;

foreach (DriveInfo drive in DriveInfo.GetDrives()) 
{ 
    if (drive.DriveType == DriveType.Removable) 
    { 
     Console.WriteLine(string.Format("({0}) {1}", drive.Name.Replace("\\",""), drive.VolumeLabel)); 
    } 
} 
+0

Sẽ trả về đĩa mềm, có thể là đầu đọc thẻ USB, các ổ Zip, Jazz và Orb có thể –

0

Adel Hazzah của answer cho mã làm việc, Daniel Widdis'sNedko's ý kiến ​​đề cập rằng bạn cần phải truy vấn Win32_USBControllerDevice và sử dụng tài sản phụ thuộc của nó, và của Daniel answer cho rất nhiều chi tiết mà không cần mã.

Dưới đây là một tổng hợp của các cuộc thảo luận ở trên để cung cấp mã làm việc liệt kê các thuộc tính thiết bị PNP truy cập trực tiếp của tất cả các thiết bị USB kết nối:

using System; 
using System.Collections.Generic; 
using System.Management; // reference required 

namespace cSharpUtilities 
{ 
    class UsbBrowser 
    { 

     public static void PrintUsbDevices() 
     { 
      IList<ManagementBaseObject> usbDevices = GetUsbDevices(); 

      foreach (ManagementBaseObject usbDevice in usbDevices) 
      { 
       Console.WriteLine("----- DEVICE -----"); 
       foreach (var property in usbDevice.Properties) 
       { 
        Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value)); 
       } 
       Console.WriteLine("------------------"); 
      } 
     } 

     public static IList<ManagementBaseObject> GetUsbDevices() 
     { 
      IList<string> usbDeviceAddresses = LookUpUsbDeviceAddresses(); 

      List<ManagementBaseObject> usbDevices = new List<ManagementBaseObject>(); 

      foreach (string usbDeviceAddress in usbDeviceAddresses) 
      { 
       // query MI for the PNP device info 
       // address must be escaped to be used in the query; luckily, the form we extracted previously is already escaped 
       ManagementObjectCollection curMoc = QueryMi("Select * from Win32_PnPEntity where PNPDeviceID = " + usbDeviceAddress); 
       foreach (ManagementBaseObject device in curMoc) 
       { 
        usbDevices.Add(device); 
       } 
      } 

      return usbDevices; 
     } 

     public static IList<string> LookUpUsbDeviceAddresses() 
     { 
      // this query gets the addressing information for connected USB devices 
      ManagementObjectCollection usbDeviceAddressInfo = QueryMi(@"Select * from Win32_USBControllerDevice"); 

      List<string> usbDeviceAddresses = new List<string>(); 

      foreach(var device in usbDeviceAddressInfo) 
      { 
       string curPnpAddress = (string)device.GetPropertyValue("Dependent"); 
       // split out the address portion of the data; note that this includes escaped backslashes and quotes 
       curPnpAddress = curPnpAddress.Split(new String[] { "DeviceID=" }, 2, StringSplitOptions.None)[1]; 

       usbDeviceAddresses.Add(curPnpAddress); 
      } 

      return usbDeviceAddresses; 
     } 

     // run a query against Windows Management Infrastructure (MI) and return the resulting collection 
     public static ManagementObjectCollection QueryMi(string query) 
     { 
      ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query); 
      ManagementObjectCollection result = managementObjectSearcher.Get(); 

      managementObjectSearcher.Dispose(); 
      return result; 
     } 

    } 

} 

Bạn sẽ cần phải thêm xử lý ngoại lệ nếu bạn muốn nó. Tham khảo câu trả lời của Daniel nếu bạn muốn tìm ra cây thiết bị và như vậy.

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