Search code examples
c#windowswmiwmi-query

C# USB flash PNPDeviceID different on some systems


I am trying to get USB flash drive ID using this code:

ManagementObjectSearcher theSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'");
foreach (ManagementObject currentObject in theSearcher.Get())
{                    
    Console.WriteLine("PNPDeviceID: " + currentObject["PNPDeviceID"]);                    
}

On most of computers I will get something like this: USBSTOR\DISK&VEN_TQ&PROD_S1&REV_1.10\11100049977&0

but on some systems for the same USB drive I get something like this: USBSTOR\DISK&VEN_TQ&PROD_S1&REV_1.10\ 6&2D2B8A01&0& 11100049977&0

Note that the part 6&2D2B8A01&0& changes depending on port that USB drive is inserted in.

How can I get the first version of the ID on every system, regardless of port USB drive is inserted in?

UPDATE 1: when using Win32_DiskDrive USB drive is detected on every PC. But when using Win32_USBHub USB drive is not detected on problematic PCs.

UPDATE 2: when using SystemUSBDrives class from this answer, on problematic PCs I get this output:

Port 1:

SystemUSBDrives PNPDeviceID: USBSTOR\DISK&VEN_TQ&PROD_S1&REV_1.10\6&2D2B8A01&0&11100049977&0
SystemUSBDrives DeviceID: \\.\PHYSICALDRIVE2
SystemUSBDrives SerialNumber:  
SystemUSBDrives VolumeSerialNumber: D6533504

Port 2:

SystemUSBDrives PNPDeviceID: USBSTOR\DISK&VEN_TQ&PROD_S1&REV_1.10\6&7A722D3&0&11100049977&0
SystemUSBDrives DeviceID: \\.\PHYSICALDRIVE2
SystemUSBDrives SerialNumber:  
SystemUSBDrives VolumeSerialNumber: D6533504

Port 3:

SystemUSBDrives PNPDeviceID: USBSTOR\DISK&VEN_TQ&PROD_S1&REV_1.10\6&32CECE73&0&11100049977&0
SystemUSBDrives DeviceID: \\.\PHYSICALDRIVE2
SystemUSBDrives SerialNumber:  
SystemUSBDrives VolumeSerialNumber: D6533504

Using this on other computers returns correct SystemUSBDrives SerialNumber value.


Solution

  • I ended up removing ParentIdPrefix from the string and it works well for my scenario:

    public static string RemoveParentIdPrefix(string pnpDeviceId)
    {
        int iSplit = pnpDeviceId.LastIndexOf("\\", StringComparison.InvariantCulture);
        string part1 = pnpDeviceId.Substring(0, iSplit);
        string part2 = pnpDeviceId.Substring(iSplit);
        int ampersandCount = 0;
        for (int i = part2.Length - 1; i >= 0; i--)
        {
            if (part2[i] == '&')
            {
                ampersandCount++;
            }
    
            if (ampersandCount == 2)
            {
                part2 = part2.Substring(i + 1);
                break;
            }
        }
        return part1 + "\\" + part2;
    }