簡體   English   中英

從USB VID / PID查找可移動磁盤的Windows驅動器號

[英]Find Windows Drive Letter of a removable disk from USB VID/PID

這個問題已經被問過,有一個答案,理應工作在這里 但是我已經嘗試過了,但是它對我不起作用。

問題是Win32_DiskDrive上的查詢返回的PNPDeviceID和“ Device”類返回的PNPDeviceID是不同的。 例如,在我的情況下,查詢返回類似-PNPDeviceID: USBSTOR \\ DISK&VEN_ABCD&PROD_1234&REV_0001 \\ 8&2C3C9390&0,而Device類返回實際的VID / PID組合-> USB \\ VID_4568&PID_QWER&MI_00 \\ 7&15b8d7f0&3&0000

因此,Win32_DiskDrive上的SELECT查詢始終失敗。

主要代碼:

    var usbDevices = GetUSBDevices();

    //Enumerate the USB devices to see if any have specific VID/PID
    foreach (var usbDevice in usbDevices)
    {
        if (usbDevice.DeviceID.Contains("ABCD") && usbDevice.DeviceID.Contains("1234"))
        {
            foreach (string name in usbDevice.GetDiskNames())
            {
                //Open dialog to show file names
                Debug.WriteLine(name);
            }
        }                   
    }

USBDeviceInfo類別

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; }

    public IEnumerable<string> GetDiskNames()
    {
        using (Device device = Device.Get(PnpDeviceID))
        {
            // get children devices
            foreach (string childDeviceId in device.ChildrenPnpDeviceIds)
            {
                // get the drive object that correspond to this id (escape the id)
                Debug.WriteLine(childDeviceId.Replace(@"\", @"\\") );
                foreach (ManagementObject drive in new ManagementObjectSearcher("SELECT DeviceID FROM Win32_DiskDrive WHERE PNPDeviceID='" + childDeviceId.Replace(@"\", @"\\") + "'").Get())
                {

                    foreach (PropertyData usb in drive.Properties){
                        if (usb.Value != null && usb.Value.ToString() != "")
                        {
                            Debug.Write(usb.Name + "=");
                            Debug.Write(usb.Value + "\r\n");
                        }
                    }

                    // associate physical disks with partitions
                    foreach (ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass=Win32_DiskDriveToDiskPartition").Get())
                    {
                        // associate partitions with logical disks (drive letter volumes)
                        foreach (ManagementObject disk in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass=Win32_LogicalDiskToPartition").Get())
                        {
                            yield return (string)disk["DeviceID"];
                        }
                    }
                }
            }
        }
    }

作為一個方面說明,我能夠用得到的查詢“模式”屬性通,然后找到驅動器盤符,如解釋在這里 但是我正在尋找一種可以將VID / PID綁定到驅動器號的解決方案。

我遇到了完全相同的問題,經過一周的辛苦工作,我終於找到了解決方案。 我還為一個設備獲得了兩個鏈接(帶有vid和pid的鏈接以及一個包含“ USBSTOR ....”的鏈接)。 我認為這不是解決問題的最佳方法,但是(直到現在)它仍然有效。

我使用了兩個功能:

第一個是找到具有特定VID和PID的USBHub,並找到相關的第二個鏈接(“ USBSTOR ....”)。 此鏈接很重要,因為它形成了與驅動器號的連接。 名為“ USBobjects”的列表包含許多相關鏈接(USBHub,USBSTOR等),這些鏈接引用了所有連接的設備。 我發現,USBSTOR鏈接出現在該鏈接之后,該鏈接包含VID和PID。 我將“ USBStOR ...”鏈接存儲為字符串,並將其用於第二個功能來查找磁盤驅動器的相關PNPEntity。 這將導致正確的DiskPartition,進而導致LogicalDisk =驅動器號。

希望不會太晚,這兩個功能都可以幫到您!

第一功能:

    public void FindPath()
    {
        foreach (ManagementObject entity in new ManagementObjectSearcher("select * from Win32_USBHub Where DeviceID Like '%VID_XXXX&PID_XXXX%'").Get())
        {
            Entity = entity["DeviceID"].ToString();

            foreach (ManagementObject controller in entity.GetRelated("Win32_USBController"))
            {
                foreach (ManagementObject obj in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_USBController.DeviceID='" + controller["PNPDeviceID"].ToString() + "'}").Get())
                {
                    if(obj.ToString().Contains("DeviceID"))
                        USBobjects.Add(obj["DeviceID"].ToString());

                }
            }

        }

        int VidPidposition = USBobjects.IndexOf(Entity);
        for (int i = VidPidposition; i <= USBobjects.Count; i++ )
        {
            if (USBobjects[i].Contains("USBSTOR"))
            {
                Secondentity = USBobjects[i];
                break;
            }

        }
    }

>

第二功能:

    public void GetDriveLetter()
    {
        foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive").Get())
            {
                if (drive["PNPDeviceID"].ToString() == Secondentity)
                {
                    foreach (ManagementObject o in drive.GetRelated("Win32_DiskPartition"))
                    {
                        foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
                        {
                            Console.WriteLine("Disk: " + i["Name"].ToString());
                        }
                    }
                }
        }
    }

>

非常感謝@Michaela的回答非常有幫助,但我認為這段代碼較短

public void FindPath()
{
   ManagementObjectSearcher entity = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
   foreach (ManagementObject obj in entity.Get())
   {
      if (obj["PNPDeviceID"].ToString().Contains("USBSTOR"))
      {
         if (!USBobjects.Contains(obj["PNPDeviceID"].ToString()))
            USBobjects.Add(obj["PNPDeviceID"].ToString());
      }
   }
}

我對GetDriveLetter()方法有另一個問題,有時編譯foreach行的時間太長。 有人可以告訴我原因嗎?

 DriveInfo[] ListDrives = DriveInfo.GetDrives();

            foreach (DriveInfo Drive in ListDrives)
            {
                if (Drive.DriveType == DriveType.Removable)
                {
                    try
                    {
                        Console.WriteLine(Drive.Name);
                    }
                    catch (Exception ex)
                    {    
                        Console.WriteLine(ex.Message);
                    }                     
                }
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM