Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# how to know if removable disk is a usb drive, or a sd card?

Tags:

c#

removable

Windows 7 platform, C#

I use the following statement to list all drives:

DriveInfo[] drives = DriveInfo.GetDrives();

then I can use DriveType to find out all those removable disks:

foreach (var drive in drives)
{
     if(drive.DriveType == DriveType.Removable)
         yield return drive;
}

now my problem is, SD-card disk and USB flashdisk shared same driveType: Removable, so how can i only find USB flashdisk out?

thanks!

like image 694
Oh My Dog Avatar asked Jul 22 '15 09:07

Oh My Dog


1 Answers

You can take advantage of ManagementObjectSearcher using it to query the disk drives that are USB, then obtain the corresponding unit letter and return only the DriveInfo of which RootDirectory.Name is contained in the result set.

Using LINQ Query Expressions:

static IEnumerable<DriveInfo> GetUsbDevices()
{
    IEnumerable<string> usbDrivesLetters = from drive in new ManagementObjectSearcher("select * from Win32_DiskDrive WHERE InterfaceType='USB'").Get().Cast<ManagementObject>()
                                           from o in drive.GetRelated("Win32_DiskPartition").Cast<ManagementObject>()
                                           from i in o.GetRelated("Win32_LogicalDisk").Cast<ManagementObject>()
                                           select string.Format("{0}\\", i["Name"]);

    return from drive in DriveInfo.GetDrives()
           where drive.DriveType == DriveType.Removable && usbDrivesLetters.Contains(drive.RootDirectory.Name)
           select drive;
}

Using LINQ Extension Methods:

static IEnumerable<DriveInfo> GetUsbDevices()
{
    IEnumerable<string> usbDrivesLetters = new ManagementObjectSearcher("select * from Win32_DiskDrive WHERE InterfaceType='USB'").Get().Cast<ManagementObject>()
        .SelectMany(drive => drive.GetRelated("Win32_DiskPartition").Cast<ManagementObject>())
        .SelectMany(o => o.GetRelated("Win32_LogicalDisk").Cast<ManagementObject>())
        .Select(i => Convert.ToString(i["Name"]) + "\\");

    return DriveInfo.GetDrives().Where(drive => drive.DriveType == DriveType.Removable && usbDrivesLetters.Contains(drive.RootDirectory.Name));
}

Using foreach:

static IEnumerable<string> GetUsbDrivesLetters()
{                
    foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive WHERE InterfaceType='USB'").Get())
        foreach (ManagementObject o in drive.GetRelated("Win32_DiskPartition"))
            foreach (ManagementObject i in o.GetRelated("Win32_LogicalDisk"))
                yield return string.Format("{0}\\", i["Name"]);
}

static IEnumerable<DriveInfo> GetUsbDevices()
{
    IEnumerable<string> usbDrivesLetters = GetUsbDrivesLetters();
    foreach (DriveInfo drive in DriveInfo.GetDrives())
        if (drive.DriveType == DriveType.Removable && usbDrivesLetters.Contains(drive.RootDirectory.Name))
            yield return drive;
}

To use ManagementObject you need to add reference to System.Management

I haven't tested it well because now I don't have any SD card, but I hope it helps

like image 126
Matteo Umili Avatar answered Oct 11 '22 23:10

Matteo Umili