The following shows how to use ManagementObjectSearcher, ManagementObject to retrieve a list of removable USB drives
Create a Windows Forms App (.NET Framework)
project
Add Reference (System.Management)
VS 2022:
- Click Project
- Select Add Reference...
- Click Assemblies
- Check System.Management
- Click OK
Add using directives
using System.IO;
using System.Management;
using System.Diagnostics;
Create a class (name: LogicalDiskInfo)
public class LogicalDiskInfo : IComparable<LogicalDiskInfo>
{
public string Description { get; set; }
public string DeviceID { get; set; }
public uint DiskIndex { get; set; }
public uint DriveType { get; set; }
public string FileSystem { get; set; }
public bool IsRemovable { get; set; } = false;
public string Name { get; set; }
public uint PartitionIndex { get; set; }
public uint PartitionNumber { get; set; }
public UInt64 Size { get; set; }
public int CompareTo(LogicalDiskInfo other)
{
if (String.Compare(this.Name, other.Name) == 0)
return 0;
else if (String.Compare(this.Name, other.Name) < 0)
return -1;
else
return 1;
}
}
Create a class (name: LogicalDisk)
public class LogicalDisk
{
public List<LogicalDiskInfo> LogicalDiskInfos = new List<LogicalDiskInfo>();
}
Create a class (name: DiskDriveInfo)
public class DiskDriveInfo : IComparable<DiskDriveInfo>
{
public string Caption { get; set; } = string.Empty;
public string DeviceID { get; set; } = string.Empty;
public List<LogicalDiskInfo> LogicalDisks { get; set; } = new List<LogicalDiskInfo>();
public UInt32 DiskIndex { get; set; } = 0;
public string InterfaceType { get; set; } = string.Empty;
public bool IsRemovable { get; set; } = false;
public string MediaType { get; set; }
public string Model { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public UInt32 Partitions { get; set; } = 0;
public string PnpDeviceID { get; set; } = string.Empty;
public UInt64 Size { get; set; } = 0;
public string Status { get; set; } = string.Empty;
public int CompareTo(DiskDriveInfo other)
{
if (this.DiskIndex == other.DiskIndex)
return 0;
else if (this.DiskIndex < other.DiskIndex)
return -1;
else
return 1;
}
}
GetUSBRemovableDiskDriveInfo:
Note: In Windows 10, it's possible to create multiple partitions on a USB flash drive. See here for more info. Therefore, it's possible that more than one drive letter may exist on the same physical disk drive. The code below works with USB drives having either a single partition or multiple partitions.
private List<DiskDriveInfo> GetUSBRemovableDiskDriveInfo()
{
SortedDictionary<uint, DiskDriveInfo> diskDict = new SortedDictionary<uint, DiskDriveInfo>();
List<DiskDriveInfo> driveInfos = new List<DiskDriveInfo>();
//MediaType: 'Removable Media'
using (ManagementObjectSearcher searcherDiskDrive = new ManagementObjectSearcher("SELECT Caption, DeviceID, Index, InterfaceType, MediaType, Model, Name, Partitions, PNPDeviceID, Size, Status FROM Win32_DiskDrive WHERE InterfaceType='USB' and MediaType='Removable Media'"))
{
foreach (ManagementObject objDiskDrive in searcherDiskDrive.Get())
{
if (objDiskDrive == null)
continue;
//create new instance
DiskDriveInfo ddInfo = new DiskDriveInfo();
//set value
uint diskIndex = Convert.ToUInt32(objDiskDrive["Index"]);
ddInfo.Caption = objDiskDrive["Caption"]?.ToString();
ddInfo.DeviceID = objDiskDrive["DeviceID"]?.ToString();
ddInfo.DiskIndex = diskIndex;
ddInfo.InterfaceType = objDiskDrive["InterfaceType"]?.ToString();
ddInfo.MediaType = objDiskDrive["MediaType"]?.ToString();
ddInfo.Model = objDiskDrive["Model"]?.ToString();
ddInfo.Name = objDiskDrive["Name"]?.ToString();
ddInfo.Partitions = Convert.ToUInt32(objDiskDrive["Partitions"]);
ddInfo.PnpDeviceID = objDiskDrive["PnpDeviceID"]?.ToString();
ddInfo.Size = Convert.ToUInt64(objDiskDrive["Size"]);
ddInfo.Status = objDiskDrive["Status"]?.ToString();
if (ddInfo.MediaType == "Removable Media")
ddInfo.IsRemovable = true;
else
ddInfo.IsRemovable = false;
if (!diskDict.ContainsKey(diskIndex))
{
//Debug.WriteLine($"Adding DiskIndex {ddInfo.DiskIndex} Partitions: {ddInfo.Partitions}");
//add
diskDict.Add(diskIndex, ddInfo);
}
}
}
//create new instance
SortedDictionary<string, LogicalDisk> logicalDiskToPartitionDict = new SortedDictionary<string, LogicalDisk>();
//get info from Win32_LogicalDiskToPartition
//this is used to associate a DiskIndex and PartitionIndex with a drive letter
using (ManagementObjectSearcher searcherLogicalDiskToPartition = new ManagementObjectSearcher($@"SELECT * FROM Win32_LogicalDiskToPartition"))
{
foreach (ManagementObject objLogicalDiskToPartition in searcherLogicalDiskToPartition.Get())
{
if (objLogicalDiskToPartition == null)
continue;
string antecedent = objLogicalDiskToPartition["Antecedent"]?.ToString();
string dependent = objLogicalDiskToPartition["Dependent"]?.ToString();
string antecedentValue = antecedent.Substring(antecedent.IndexOf('=') + 1).Replace("\"", "");
uint diskIndex = 0;
uint partitionIndex = 0;
//get disk index and convert to uint
UInt32.TryParse(antecedentValue.Substring(antecedentValue.IndexOf("#") + 1, antecedentValue.IndexOf(",") - (antecedentValue.IndexOf("#") + 1)), out diskIndex);
//get partition index and convert to uint
UInt32.TryParse(antecedentValue.Substring(antecedentValue.LastIndexOf("#") + 1), out partitionIndex);
string driveLetter = dependent.Substring(dependent.IndexOf("=") + 1).Replace("\"", "");
if (diskDict.ContainsKey(diskIndex))
{
if (!logicalDiskToPartitionDict.ContainsKey(driveLetter))
{
//add
logicalDiskToPartitionDict.Add(driveLetter, new LogicalDisk());
}
//get info from Win32_LogicalDisk
using (ManagementObjectSearcher searcherLogicalDisk = new ManagementObjectSearcher($"SELECT Description, DeviceID, DriveType, FileSystem, Name, Size FROM Win32_LogicalDisk WHERE Name = '{driveLetter}'"))
{
foreach (ManagementObject objLogicalDisk in searcherLogicalDisk.Get())
{
if (objLogicalDisk == null)
continue;
//create new instance
LogicalDiskInfo logicalDiskInfo = new LogicalDiskInfo();
//set value
logicalDiskInfo.Description = objLogicalDisk["Description"]?.ToString();
logicalDiskInfo.DeviceID = objLogicalDisk["DeviceID"]?.ToString();
logicalDiskInfo.DriveType = Convert.ToUInt32(objLogicalDisk["DriveType"]);
logicalDiskInfo.DiskIndex = diskIndex;
logicalDiskInfo.FileSystem = objLogicalDisk["FileSystem"]?.ToString();
logicalDiskInfo.Name = objLogicalDisk["Name"]?.ToString();
logicalDiskInfo.PartitionIndex = partitionIndex;
logicalDiskInfo.PartitionNumber = partitionIndex + 1; //diskpart partitions start at 1
logicalDiskInfo.Size = Convert.ToUInt64(objLogicalDisk["Size"]);
//DriveType: 2=Removable; 3=Local Disk; 4=Network Drive; 5=CD
if (logicalDiskInfo.DriveType == 2)
logicalDiskInfo.IsRemovable = true;
else
logicalDiskInfo.IsRemovable = false;
Debug.WriteLine($"adding logicalDiskInfo for DiskIndex: '{diskIndex}' PartitionIndex: '{partitionIndex}' PartitionNumber: '{logicalDiskInfo.PartitionNumber}'");
//add
logicalDiskToPartitionDict[driveLetter].LogicalDiskInfos.Add(logicalDiskInfo);
}
}
}
}
}
//add logical disk info to disk dictionary
foreach(KeyValuePair<string, LogicalDisk> kvp in logicalDiskToPartitionDict)
{
List<LogicalDiskInfo> logicalDiskInfoList = kvp.Value.LogicalDiskInfos;
//sort
logicalDiskInfoList.Sort();
foreach (LogicalDiskInfo ldInfo in logicalDiskInfoList)
{
//add
diskDict[ldInfo.DiskIndex].LogicalDisks.Add(ldInfo);
}
}
//only add disks that are listed as 'Removable'
foreach(KeyValuePair<uint, DiskDriveInfo> kvp in diskDict)
{
if (kvp.Value.IsRemovable)
{
//add
driveInfos.Add(kvp.Value);
}
}
return driveInfos;
}
Usage:
System.Diagnostics.Debug.WriteLine("--------GetUSBRemovableDiskDriveInfo----------");
foreach (DiskDriveInfo ddInfo in GetUSBRemovableDiskDriveInfo())
{
string driveLetters = string.Empty;
for (int i = 0; i < ddInfo.LogicalDisks.Count; i++)
{
if (i > 0)
driveLetters += ", ";
driveLetters += ddInfo.LogicalDisks[i].Name;
}
System.Diagnostics.Debug.WriteLine($"Caption: '{ddInfo.Caption}' Name: '{ddInfo.Name}' DiskIndex: '{ddInfo.DiskIndex}' DriveLetters: [{driveLetters}] Partitions: '{ddInfo.Partitions}' Size: '{ddInfo.Size}'");
}
One can use System.Diagnostics.Process to execute a diskpart script to clean one or more disks. See this post for more info.
Resources: