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

2

15

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!

Cuesta answered 22/7, 2015 at 9:27 Comment(0)
M
7

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

Milliard answered 22/7, 2015 at 10:16 Comment(6)
hi @codroipo, usbDrivesLetters returns all removable drives, including the sd-card. But i love ManagementObjectSearcher it looks much more professional lol, so would you please help a more little how to filt out only the usb drive?Cuesta
@OhMyDog In Device manager, under which node is shown your SD Card Reader?Milliard
@OhMyDog Can you also tell me what is the output of new ManagementObjectSearcher("select * from Win32_DiskDrive WHERE InterfaceType='USB'").Get().Cast<ManagementObject>().Select(f => (string)f["PNPDeviceID"]).ToList()?Milliard
problem solved. I check pnpDeviceID and found difference between USB-flash and SD-card, thank you codroipo!Cuesta
Could you please edit your answer to be correct, after you know how to do it now? ThxBrach
In windows 10 the Win32_DiskDrive InterfaceType='USB' is not returning all USB drives (they return InterfaceType='SCSI'). I think it has to do with type-c USB drives. )-:Publicist
G
1

I had to check for USB-Devices in an older project and solved it like this:

 Win32.DEV_BROADCAST_DEVICEINTERFACE deviceInterface;
 deviceInterface = (Win32.DEV_BROADCAST_DEVICEINTERFACE)
 string name = new string(deviceInterface.dbcc_name);
 Guid g = new Guid(deviceInterface.dbcc_classguid);
 if (g.ToString() == "a5dcbf10-6530-11d2-901f-00c04fb951ed")
 {*DO SOMETHING*}

I get the GUID and check if the devices GUID is the USB-GUID.

Gentlemanly answered 22/7, 2015 at 9:36 Comment(2)
I am not completely sure, but I think the OP doesn't have the GUIDBeghard
also thank you npit, but i focused on codroipo's answer, sorry for not trying yours.Cuesta

© 2022 - 2024 — McMap. All rights reserved.