How to get the drive letter of USB device using WMI

前端 未结 2 1812
野性不改
野性不改 2021-02-04 21:17

I need to track the USB insertion and removal events from the C# application so I came up with the following ideas based on the other questions on SO.

I can\'t use this

相关标签:
2条回答
  • 2021-02-04 21:38

    You get an exception because your deviceID contains characters that need to be escaped (backslashes). With simple replace you shouldn't get the exception.

    string query = string.Format("SELECT * FROM Win32_LogicalDisk WHERE DeviceID='{0}'", deviceID.Replace(@"\", @"\\"));
    

    However, getting USB drive letter from WMI is a little more complicated. You need to go through a few classes, as stated in a link that @MSalters posted in his comment:

    Win32_DiskDrive-> Win32_DiskDriveToDiskPartition -> Win32_DiskPartition -> Win32_LogicalDiskToPartition -> Win32_LogicalDisk.
    

    A little modified version of code found here worked for me:

    foreach (ManagementObject device in new ManagementObjectSearcher(@"SELECT * FROM Win32_DiskDrive WHERE InterfaceType LIKE 'USB%'").Get())
    {
        Console.WriteLine((string)device.GetPropertyValue("DeviceID"));
        Console.WriteLine((string)device.GetPropertyValue("PNPDeviceID"));                
    
        foreach (ManagementObject partition in new ManagementObjectSearcher(
            "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + device.Properties["DeviceID"].Value
            + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
        {
            foreach (ManagementObject disk in new ManagementObjectSearcher(
                        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"
                            + partition["DeviceID"]
                            + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
            {
                Console.WriteLine("Drive letter " + disk["Name"]);
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-04 21:51

    This is a refactored version of michalk's answer for C# 8.

    I used it in combination with the answers for this, Detecting USB drive insertion and removal using windows service and c#, related question

            static IEnumerable<(string deviceId, string pnpDeviceId, string driveLetter)> SelectDeviceInformation()
            {
                foreach (ManagementObject device in SelectDevices())
                {
                    var deviceId = (string)device.GetPropertyValue("DeviceID");
                    var pnpDeviceId = (string)device.GetPropertyValue("PNPDeviceID");
                    var driveLetter = (string)SelectPartitions(device).SelectMany(SelectDisks).Select(disk => disk["Name"]).Single();
    
                    yield return (deviceId, pnpDeviceId, driveLetter);
                }
    
                static IEnumerable<ManagementObject> SelectDevices() => new ManagementObjectSearcher(
                        @"SELECT * FROM Win32_DiskDrive WHERE InterfaceType LIKE 'USB%'").Get()
                    .Cast<ManagementObject>();
    
                static IEnumerable<ManagementObject> SelectPartitions(ManagementObject device) => new ManagementObjectSearcher(
                        "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=" +
                        "'" + device.Properties["DeviceID"].Value + "'} " +
                        "WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get()
                    .Cast<ManagementObject>();
    
                static IEnumerable<ManagementObject> SelectDisks(ManagementObject partition) => new ManagementObjectSearcher(
                        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID=" +
                        "'" + partition["DeviceID"] + "'" +
                        "} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()
                    .Cast<ManagementObject>();
            }
    
    0 讨论(0)
提交回复
热议问题