title: Find USB drive letter from VID/PID (Needed for XP and higher)
body: <p>So I thought I would include the final answer here so you don't have to make sense of this post. Big thanks to Simon Mourier for taking the time to figure this one out.</p>
  
  <p><strong>MY WORKING CODE</strong></p>
  
  <pre><code>        try
          {
              //Get a list of available devices attached to the USB hub
              List&lt;string&gt; disks = new List&lt;string&gt;();
              var usbDevices = GetUSBDevices();
  
              //Enumerate the USB devices to see if any have specific VID/PID
              foreach (var usbDevice in usbDevices)
              {
                  if (usbDevice.DeviceID.Contains(USB_PID) &amp;&amp; usbDevice.DeviceID.Contains(USB_VID))
                  {
                      foreach (string name in usbDevice.GetDiskNames())
                      {
                          //Open dialog to show file names
                          textbox1.Text = name.ToString();
                      }
                  }                   
              }
  </code></pre>
  
  <p>So just use <code>GetUSBDevices</code> from my original question and then include the two classes shown by Simon Mourier's answer and it should be good to go!</p>
  
  <hr>
  
  <p><strong>ORIGINAL QUESTION</strong></p>
  
  <p>I know this question has been asked before (see <a href="https://stackoverflow.com/questions/15740613/how-to-find-the-drive-letter-of-an-usb-mass-storage-drive-using-vid-and-pid-in-c?rq=1">here</a>) but none of them have a confirmed answer and I've tried all of the suggested answers. Unfortunately those threads are long dead and I was hoping someone could give a better answer here. </p>
  
  <p>So far I have two 'starting points', each of which I'll show below.</p>
  
  <hr>
  
  <p><strong>OPTION 1</strong>: (gets VID/PID but not drive letter)</p>
  
  <p>I have an embedded device which I connect to through an application. I have code which succesfully scans any USB devices and checks the <code>VID/PID</code>. I successfully detect my device but I have no idea how to get the drive letter. Can someone help me out? I feel like I could add another line in the <code>class</code> but when I go through <code>Device Manager</code> I can't find any property there that describes the drive letter.</p>
  
  <p>Thanks!</p>
  
  <p>I'll include my code so far below.</p>
  
  <pre><code>private void tsDownload_Click(object sender, EventArgs e)
      {
          var usbDevices = GetUSBDevices();
  
          foreach (var usbDevice in usbDevices)
          {
              if (usbDevice.DeviceID.Contains(USB_PID) &amp;&amp; usbDevice.DeviceID.Contains(USB_VID))
              {                    
                  //Find drive letter here
              }
          }
      }
  </code></pre>
  
  <p>where those functions are:</p>
  
  <pre><code> static List&lt;USBDeviceInfo&gt; GetUSBDevices()
      {
        List&lt;USBDeviceInfo&gt; devices = new List&lt;USBDeviceInfo&gt;();
  
        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;
      }      
  </code></pre>
  
  <p>and the class is:</p>
  
  <pre><code>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; }
  }
  </code></pre>
  
  <hr>
  
  <p><strong>OPTION 2</strong>: (get drive letter but not VID/PID)</p>
  
  <pre><code>foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive where InterfaceType='USB'").Get())
              {
                  foreach(ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
                  {
                      foreach (ManagementObject disk in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
                      {
                          textBox1.Text = disk["Name"].ToString();
  
                      }
                  }
              }
  </code></pre>
  
  <p>I'm going to guess the VID/PID is in one of the <code>disk</code> object properties but I just can't find which one.</p>