Search code examples
c#hardware

Get Serial Number of Boot Drive and other info


I am trying to get the serial number of the boot drive and I haven't figured out how to do it.

I do understand that the partition =\= hard drive but I'd like the serial of the boot partition.

This what I have so far:

        var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");

        int i = 0;
        foreach (ManagementObject wmi_HD in searcher.Get())
        {
            // get the hardware serial no.
            if (wmi_HD["SerialNumber"] == null)
                richTextBox1.Text += "None" + Environment.NewLine;
            else
                richTextBox1.Text += "Name: " + wmi_HD["Name"] + Environment.NewLine;
                richTextBox1.Text += "SerialNumber: " + wmi_HD["SerialNumber"] + Environment.NewLine;
                richTextBox1.Text += "MediaType: " + wmi_HD["MediaType"] + Environment.NewLine;
                richTextBox1.Text += "Removable: " + wmi_HD["Removable"] + Environment.NewLine;

            ++i;
        }

I have looked here:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa394346(v=vs.85).aspx#properties

To see if I could see if it was the boot drive and I don't see anything.

I'm getting nothing returned on anything but the SerialNumber, everything else is blank.

This is what I get on the above code:

Name:

SerialNumber: 5YZ01J34

MediaType:

Removable:

How do I get the serial number of the boot drive and also the information that is not showing above?

Thanks again!


Solution

  • Here you're talking about a drive (as it's bootable), not a disk. A drive is logical and represented by a letter (C, D....etc.), and a disk is physical and represented by a number (from 0 to N). In your example you used WMI and Win32_PhysicalMedia, which is wrong as this class is about disks, not drives.

    Here is what you want using P/Invoke:

    namespace ConsoleApplication3
    {
        using System.Runtime.InteropServices;
        using System.Text;
    
        public class Drive
        {
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool GetVolumeInformation(
                string rootPathName,
                StringBuilder volumeNameBuffer,
                int volumeNameSize,
                ref uint volumeSerialNumber,
                ref uint maximumComponentLength,
                ref uint fileSystemFlags,
                StringBuilder fileSystemNameBuffer,
                int nFileSystemNameSize);
    
            public string VolumeName { get; private set; }
    
            public string FileSystemName { get; private set; }
    
            public uint SerialNumber { get; private set; }
    
            public string DriveLetter { get; private set; }
    
            public static Drive GetDrive(string driveLetter)
            {
                const int VolumeNameSize = 255;
                const int FileSystemNameBufferSize = 255;
                StringBuilder volumeNameBuffer = new StringBuilder(VolumeNameSize);
                uint volumeSerialNumber = 0;
                uint maximumComponentLength = 0;
                uint fileSystemFeatures = 0;
                StringBuilder fileSystemNameBuffer = new StringBuilder(FileSystemNameBufferSize);
    
                if (GetVolumeInformation(
                    string.Format("{0}:\\", driveLetter),
                    volumeNameBuffer,
                    VolumeNameSize,
                    ref volumeSerialNumber,
                    ref maximumComponentLength,
                    ref fileSystemFeatures,
                    fileSystemNameBuffer,
                    FileSystemNameBufferSize))
                {
                    return new Drive
                        {
                            DriveLetter = driveLetter,
                            FileSystemName = fileSystemNameBuffer.ToString(),
                            VolumeName = volumeNameBuffer.ToString(),
                            SerialNumber = volumeSerialNumber
                        };
                }
    
                // Something failed, returns null
                return null;
            }
        }
    }
    
    
    Drive drive = Drive.GetDrive("C");
    
    Console.WriteLine(string.Format("Volumne name: {0}", drive.VolumeName));
    Console.WriteLine(string.Format("File system name: {0}", drive.FileSystemName));
    Console.WriteLine(string.Format("SerialNumber: {0:X}", drive.SerialNumber));
    

    Now, the same using WMI:

    var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk");
    
    foreach (ManagementObject drive in searcher.Get())
    {
        Console.WriteLine("-------");
        Console.WriteLine(string.Format("VolumeName: {0}", drive["VolumeName"]));
        Console.WriteLine(string.Format("VolumeSerialNumber: {0}", drive["VolumeSerialNumber"]));
        Console.WriteLine(string.Format("MediaType: {0}", drive["MediaType"]));
        Console.WriteLine(string.Format("FileSystem: {0}", drive["FileSystem"]));
    }
    

    Note I've used Win32_LogicalDisk as we're talking about drives (named here logical disks).