18

I need to check in C# if a hard disk is SSD (Solid-state drive), no seek penalty? I used:

 ManagementClass driveClass = new ManagementClass("Win32_DiskDrive"); ManagementObjectCollection drives = driveClass.GetInstances(); 

But its only gives Strings that contain SSD in the properties, I can't depend on that?

I Need a direct way to check that?

7
  • You could maintain a list of hardware identifiers of SSD drives, and check against that. Sure, that is an evolving list... Commented Dec 5, 2012 at 15:28
  • 2
    +1 for getting beat up. I could see how you might use this to flop between a memory or disk based approach. It takes time to measure access time. Commented Dec 5, 2012 at 15:57
  • Hybrid drives are a lost cause as well. Got one in my new laptop, the C: drive is a hard disk with a 20 GB SSD. This is just not a problem that ever needs to be solved. Commented Dec 5, 2012 at 16:36
  • 1
    @Blam I do not beat up anyone, I ask a sincere question. There is no fool proof way to detect an SSD, but there are ways to measure latency and throughput. If OP wants to make decisions based on that (as not to exclude hybrid drives and future fast storage devices (does a USB 3 flash drive count?)), that question should be answered before a helpful answer can be given. Commented Dec 5, 2012 at 16:45
  • I just need to check if the system Particular that contains the current running OS is on SSD hard disk or not without needing any Admin privileges or writing a file. Commented Dec 6, 2012 at 8:02

3 Answers 3

13

WMI will not be able to determine this easily. There is a solution here that's based on the same algorithm Windows 7 uses to determine if a disk is SSD (more on the algorithm here: Windows 7 Enhancements for Solid-State Drives, page 8 and also here: Windows 7 Disk Defragmenter User Interface Overview): Tell whether SSD or not in C#

A quote from the MSDN blog:

Disk Defragmenter looks at the result of directly querying the device through the ATA IDENTIFY DEVICE command. Defragmenter issues IOCTL_ATA_PASS_THROUGH request and checks IDENTIFY_DEVICE_DATA structure. If the NomimalMediaRotationRate is set to 1, this disk is considered a SSD. The latest SSDs will respond to the command by setting word 217 (which is used for reporting the nominal media rotation rate to 1). The word 217 was introduced in 2007 in the ATA8-ACS specification.

Sign up to request clarification or add additional context in comments.

6 Comments

Problem with this approach is that it won't detect whether a storage is an SSD, but just check if it has low latency and high throughput. Hence my question to OP. :-)
@CodeCaster - I don't agree. It's capable of testing the nominal ATA media rotation rate which should be set to 1 ('non rotating media') for SSD. See t13.org/documents/UploadedDocuments/docs2007/… page 139, although some SSD disks/drivers could actually not implement this.
Actually it works fine, and I found this solution before but it still writes a file and needs privilege.
@KhaleelHmoz - are you using the 'nominal media rotation rate' method (choice 1)?
Oh, it's not really creating a file, the CreateFile API is used to open the drive to be able to use an API on it, but yes, the 'media rotation method' needs administrative privilege. Have you tried the 'no seek penalty' method?
|
10

This will give you the result on Win10

ManagementScope scope = new ManagementScope(@"\\.\root\microsoft\windows\storage"); ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM MSFT_PhysicalDisk"); string type = ""; scope.Connect(); searcher.Scope = scope; foreach (ManagementObject queryObj in searcher.Get()) { switch (Convert.ToInt16(queryObj["MediaType"])) { case 1: type = "Unspecified"; break; case 3: type = "HDD"; break; case 4: type = "SSD"; break; case 5: type = "SCM"; break; default: type = "Unspecified"; break; } } searcher.Dispose(); 

P.s. the string type is the last drive, change to an array to get it for all drives

1 Comment

System.Management.ManagementException: 'Invalid class ', me = sad ;(
0

This is how to check drive type by string path.

public enum DriveType { None = 0, Hdd, Ssd } public static DriveType GetDriveType(string path) { try { var rootPath = Path.GetPathRoot(path); if (string.IsNullOrEmpty(rootPath)) { return DriveType.None; } rootPath = rootPath[0].ToString(); var scope = new ManagementScope(@"\\.\root\microsoft\windows\storage"); scope.Connect(); using var partitionSearcher = new ManagementObjectSearcher($"select * from MSFT_Partition where DriveLetter='{rootPath}'"); partitionSearcher.Scope = scope; var partitions = partitionSearcher.Get(); if (partitions.Count == 0) { return DriveType.None; } string? diskNumber = null; foreach (var currentPartition in partitions) { diskNumber = currentPartition["DiskNumber"].ToString(); if (!string.IsNullOrEmpty(diskNumber)) { break; } } if (string.IsNullOrEmpty(diskNumber)) { return DriveType.None; } using var diskSearcher = new ManagementObjectSearcher($"SELECT * FROM MSFT_PhysicalDisk WHERE DeviceId='{diskNumber}'"); diskSearcher.Scope = scope; var physicakDisks = diskSearcher.Get(); if (physicakDisks.Count == 0) { return DriveType.None; } foreach (var currentDisk in physicakDisks) { var mediaType = Convert.ToInt16(currentDisk["MediaType"]); switch (mediaType) { case 3: return DriveType.Hdd; case 4: return DriveType.Ssd; default: return DriveType.None; } } return DriveType.None; } catch (Exception ex) { // TODO: Log error. return DriveType.None; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.