How to get the drive letter of an SD Card connected to a PC, from a C# .NET Framework application?
I have looked at suggested questions on this topic, including this, this & this, but none of them give me the solution I need.
Using System.IO.DriveInfo.GetDrives() or System.Management.ManagementObjectSearcher() with query "Win32_LogicalDisk", I can get the drive letters of all devices, but I can't tell which device(s) is the SD card. Using System.Management.ManagementObjectSearcher() with query "CIM_LogicalDevice", "Caption = 'SDHC Card'", I get 2 devices with the "SDHC Card" caption property, but no drive letters.
How can I get the drive letter of the SD Card or card reader?
Here is what I have tried so far:
using System;
using System.Management;
namespace Code3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\tfrom: 'ManagementObjectSearcher()' with query \"Win32_LogicalDisk\"");
var searcher1 = new ManagementObjectSearcher(@"\root\cimv2", "SELECT * FROM Win32_LogicalDisk");
foreach (ManagementBaseObject disk in searcher1.Get())
{
string diskID = disk.GetPropertyValue("DeviceID").ToString();
int driveType = Convert.ToInt32(disk.GetPropertyValue("DriveType"));
string diskCaption = disk.GetPropertyValue("Caption").ToString();
string diskDescription = disk.GetPropertyValue("Description").ToString();
string diskName = disk.GetPropertyValue("Name").ToString();
int diskMediaType = Convert.ToInt32(disk.GetPropertyValue("MediaType"));
Console.WriteLine($"{diskName} - ID: {diskID}, Caption: {diskCaption}, Desc.: {diskDescription,-16}, Drive Type: {driveType}, Media Type: {diskMediaType}.");
}
Console.WriteLine();
Console.WriteLine("\tfrom: 'ManagementObjectSearcher()' with query SelectQuery(\"CIM_LogicalDevice\", \"Caption = 'SDHC Card'\")");
ManagementScope mgmtScope = new ManagementScope(@"\root\cimv2");
SelectQuery devQuery = new SelectQuery("CIM_LogicalDevice", "Caption = 'SDHC Card'");
var searcher2 = new ManagementObjectSearcher(mgmtScope, devQuery);
foreach (ManagementBaseObject device in searcher2.Get())
{
Console.WriteLine($"{device.GetPropertyValue("Name"),-15} - Caption: {device.GetPropertyValue("Caption")}, Device ID: {device.GetPropertyValue("DeviceID")}.");
continue; // ... to skip property display
if (!string.IsNullOrEmpty(device.GetPropertyValue("Name").ToString()))
{
PropertyDataCollection props = device.Properties;
Console.WriteLine($"\n\t\tProperties of {device.GetPropertyValue("DeviceID")} Drive: \n");
foreach (var prop in device.Properties)
{
if (prop.Value != null)
Console.WriteLine($"{prop.Name,-20} - {prop.Type,-8} - {prop.Value ?? "(null)"}");
}
Console.WriteLine();
}
}
Console.ReadKey();
}
}
}
Thank you for any help you can give me.
EDIT: From "CIM_LogicalDisk", I can see that "F:" drive is my SD-Card. (from 'VolumeName' property.)
From "CIM_LogicalDevice", I can see the "\.\PHYSICALDRIVE1" and "PCISTOR\DISK&VEN_RSPER&PROD_RTS5208LUN0&REV_1.00\0000" is my SD-Card. (from 'Name', 'Caption', and/or 'Model' properties.)
But my app can't see this! Note that 'drive letter' and 'PHYSICALDRIVE number' do not remain correlated, and can change as different removable devices are inserted and removed.
How can I get my code to make the connection between logical and physical drives?