获取硬盘序列号

时间:2010-11-03 05:15:31

标签: c# hard-drive

我想获得硬盘序列号。我怎么能这样做? 我尝试了两个代码,但我没有得到

StringCollection propNames = new StringCollection();
ManagementClass driveClass = new ManagementClass("Win32_DiskDrive");
PropertyDataCollection  props = driveClass.Properties;
foreach (PropertyData driveProperty in props) 
{
    propNames.Add(driveProperty.Name);
}
int idx = 0;
ManagementObjectCollection drives = driveClass.GetInstances();
foreach (ManagementObject drv in drives)
       {
          Label2.Text+=(idx + 1);
          foreach (string strProp in propNames)
           {
            //Label2.Text+=drv[strProp];
         Response.Write(strProp + "   =   " + drv[strProp] + "</br>");
          }
    }

在这个中我没有得到任何唯一序列号 第二个是

string drive = "C";
ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + drive + ":\"");
disk.Get();
Label3.Text = "VolumeSerialNumber="+ disk["VolumeSerialNumber"].ToString();

我在这里得到VolumeSerialNumber。但它并不是独一无二的。如果我格式化硬盘,这将改变。我怎么能得到这个?

10 个答案:

答案 0 :(得分:35)

嗯,看着你的第一组代码,我想你已经检索过(可能是?)硬盘驱动器型号。序列号#来自Win32_PhysicalMedia

获取硬盘型号

    ManagementObjectSearcher searcher = new
    ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");

   foreach(ManagementObject wmi_HD in searcher.Get())
   {
    HardDrive hd = new HardDrive();
    hd.Model = wmi_HD["Model"].ToString();
    hd.Type  = wmi_HD["InterfaceType"].ToString(); 
    hdCollection.Add(hd);
   }

获取序列号

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

   int i = 0;
   foreach(ManagementObject wmi_HD in searcher.Get())
   {
    // get the hard drive from collection
    // using index
    HardDrive hd = (HardDrive)hdCollection[i];

    // get the hardware serial no.
    if (wmi_HD["SerialNumber"] == null)
     hd.SerialNo = "None";
    else
     hd.SerialNo = wmi_HD["SerialNumber"].ToString();

    ++i;
   }

Source

希望这会有所帮助:)

答案 1 :(得分:11)

我在项目中使用了以下方法,并且它已成功运行。

private string identifier(string wmiClass, string wmiProperty)
//Return a hardware identifier
{
    string result = "";
    System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    System.Management.ManagementObjectCollection moc = mc.GetInstances();
    foreach (System.Management.ManagementObject mo in moc)
    {
        //Only get the first one
        if (result == "")
        {
            try
            {
                result = mo[wmiProperty].ToString();
                break;
            }
            catch
            {
            }
        }
    }
    return result;
}

你可以调用上面提到的方法,

string modelNo = identifier("Win32_DiskDrive", "Model");
string manufatureID = identifier("Win32_DiskDrive", "Manufacturer");
string signature = identifier("Win32_DiskDrive", "Signature");
string totalHeads = identifier("Win32_DiskDrive", "TotalHeads");

如果您需要唯一标识符,请使用这些ID的组合。

答案 2 :(得分:8)

@ Sprunth的答案有一个简单的方法。

private void GetAllDiskDrives()
    {
        var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");

        foreach (ManagementObject wmi_HD in searcher.Get())
        {
            HardDrive hd = new HardDrive();
            hd.Model = wmi_HD["Model"].ToString();
            hd.InterfaceType = wmi_HD["InterfaceType"].ToString();
            hd.Caption = wmi_HD["Caption"].ToString();

            hd.SerialNo =wmi_HD.GetPropertyValue("SerialNumber").ToString();//get the serailNumber of diskdrive

            hdCollection.Add(hd);
        }

 }


public class HardDrive
{
    public string Model { get; set; }
    public string InterfaceType { get; set; }
    public string Caption { get; set; }
    public string SerialNo { get; set; }
}

答案 3 :(得分:3)

使用“vol”shell命令并从其输出中解析serial,就像这样。 至少在Win7中起作用

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CheckHD
{
        class HDSerial
        {
            const string MY_SERIAL = "F845-BB23";
            public static bool CheckSerial()
            {
                string res = ExecuteCommandSync("vol");
                const string search = "Number is";
                int startI = res.IndexOf(search, StringComparison.InvariantCultureIgnoreCase);

                if (startI > 0)
                {
                    string currentDiskID = res.Substring(startI + search.Length).Trim();
                    if (currentDiskID.Equals(MY_SERIAL))
                        return true;
                }
                return false;
            }

            public static string ExecuteCommandSync(object command)
            {
                try
                {
                    // create the ProcessStartInfo using "cmd" as the program to be run,
                    // and "/c " as the parameters.
                    // Incidentally, /c tells cmd that we want it to execute the command that follows,
                    // and then exit.
                    System.Diagnostics.ProcessStartInfo procStartInfo =
                        new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

                    // The following commands are needed to redirect the standard output.
                    // This means that it will be redirected to the Process.StandardOutput StreamReader.
                    procStartInfo.RedirectStandardOutput = true;
                    procStartInfo.UseShellExecute = false;
                    // Do not create the black window.
                    procStartInfo.CreateNoWindow = true;
                    // Now we create a process, assign its ProcessStartInfo and start it
                    System.Diagnostics.Process proc = new System.Diagnostics.Process();
                    proc.StartInfo = procStartInfo;
                    proc.Start();
                    // Get the output into a string
                    string result = proc.StandardOutput.ReadToEnd();
                    // Display the command output.
                    return result;
                }
                catch (Exception)
                {
                    // Log the exception
                    return null;
                }
            }
        }
    }

答案 4 :(得分:0)

我发现的最佳方法是从here

下载dll

然后,将dll添加到项目中。

然后,添加代码:

[DllImportAttribute("HardwareIDExtractorC.dll")]
public static extern String GetIDESerialNumber(byte DriveNumber);

然后,从您需要的地方调用硬盘ID

GetIDESerialNumber(0).Replace(" ", string.Empty);

注意:转到资源管理器中的dll属性并将“Build action”设置为“Embedded Resource”

答案 5 :(得分:0)

以下是获取硬盘序列号的全功能方法:

public string GetHardDiskSerialNo()
    {
        ManagementClass mangnmt = new ManagementClass("Win32_LogicalDisk");
        ManagementObjectCollection mcol = mangnmt.GetInstances();
        string result = "";
        foreach (ManagementObject strt in mcol)
        {
            result += Convert.ToString(strt["VolumeSerialNumber"]);
        }
        return result;
    }

答案 6 :(得分:0)

我正在使用它:

<!-- language: c# -->
private static string wmiProperty(string wmiClass, string wmiProperty){
  using (var searcher = new ManagementObjectSearcher($"SELECT * FROM {wmiClass}")) {
   try {
                    IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
                    return objects.Select(x => x.GetPropertyValue(wmiProperty)).FirstOrDefault().ToString().Trim();
                } catch (NullReferenceException) {
                    return null;
                }
            }
        }

答案 7 :(得分:0)

以下是一些可能有用的代码:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");

string serial_number="";

foreach (ManagementObject wmi_HD in searcher.Get())
{
    serial_number = wmi_HD["SerialNumber"].ToString();
}

MessageBox.Show(serial_number);

答案 8 :(得分:0)

这里是使用win32 api和std字符串的解决方案,以防您需要应用程序在没有CLR的操作系统上运行。我在github上找到了它。

#include "stdafx.h"
#include <windows.h>
#include <memory>
#include <string>

//returns the serial number of the first physical drive in a std::string or an empty std::string in case of failure
//based on http://codexpert.ro/blog/2013/10/26/get-physical-drive-serial-number-part-1/
std::string getFirstHddSerialNumber() {
    //get a handle to the first physical drive
    HANDLE h = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (h == INVALID_HANDLE_VALUE) return{};
    //an std::unique_ptr is used to perform cleanup automatically when returning (i.e. to avoid code duplication)
    std::unique_ptr<std::remove_pointer<HANDLE>::type, void(*)(HANDLE)> hDevice{ h, [](HANDLE handle){CloseHandle(handle); } };
    //initialize a STORAGE_PROPERTY_QUERY data structure (to be used as input to DeviceIoControl)
    STORAGE_PROPERTY_QUERY storagePropertyQuery{};
    storagePropertyQuery.PropertyId = StorageDeviceProperty;
    storagePropertyQuery.QueryType = PropertyStandardQuery;
    //initialize a STORAGE_DESCRIPTOR_HEADER data structure (to be used as output from DeviceIoControl)
    STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader{};
    //the next call to DeviceIoControl retrieves necessary size (in order to allocate a suitable buffer)
    //call DeviceIoControl and return an empty std::string on failure
    DWORD dwBytesReturned = 0;
    if (!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
        &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &dwBytesReturned, NULL))
        return{};
    //allocate a suitable buffer
    const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
    std::unique_ptr<BYTE[]> pOutBuffer{ new BYTE[dwOutBufferSize]{} };
    //call DeviceIoControl with the allocated buffer
    if (!DeviceIoControl(hDevice.get(), IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
        pOutBuffer.get(), dwOutBufferSize, &dwBytesReturned, NULL))
        return{};
    //read and return the serial number out of the output buffer
    STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(pOutBuffer.get());
    const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
    if (dwSerialNumberOffset == 0) return{};
    const char* serialNumber = reinterpret_cast<const char*>(pOutBuffer.get() + dwSerialNumberOffset);
    return serialNumber;
}

#include <iostream>
int main() {
    std::string serialNumber = getFirstHddSerialNumber();
    if (serialNumber.empty())
        std::cout << "failed to retrieve serial number\n";
    else
        std::cout << "serial number: " << serialNumber << "\n";
    return 0;
}

答案 9 :(得分:0)

如果要使用它进行复制保护,并且需要它在一台计算机上返回始终相同的序列(当然,只要第一个hdd或ssd没有更改),我建议使用以下代码。对于ManagementClass,您需要添加对System.Management的引用。附言如果没有“ InterfaceType”和“ DeviceID”,请检查该方法是否可以返回随机磁盘的序列或当前已连接到PC的USB闪存驱动器的序列。

    public static string GetSerial()
    {
        try
        {
            var mc = new ManagementClass("Win32_DiskDrive");
            var moc = mc.GetInstances();
            var res = string.Empty;
            var resList = new List<string>(moc.Count);

            foreach (ManagementObject mo in moc)
            {
                try
                {
                    if (mo["InterfaceType"].ToString().Replace(" ", string.Empty) == "USB")
                    {
                        continue;
                    }
                }
                catch
                {
                }

                try
                {
                    res = mo["SerialNumber"].ToString().Replace(" ", string.Empty);
                    resList.Add(res);
                    if (mo["DeviceID"].ToString().Replace(" ", string.Empty).Contains("0"))
                    {
                        if (!string.IsNullOrWhiteSpace(res))
                        {
                            return res;
                        }
                    }
                }
                catch
                {
                }
            }

            res = resList[0];
            if (!string.IsNullOrWhiteSpace(res))
            {
                return res;
            }
        }
        catch
        {
        }

        return string.Empty;
    }