web-dev-qa-db-fra.com

Obtenir le numéro de série du disque dur

Je veux obtenir le numéro de série du disque dur. Comment puis-je faire cela? J'ai essayé avec deux codes mais je ne reçois

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>");
          }
    }

Dans celui-ci, je ne reçois aucun numéro de série unique.
Et le second est 

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

Ici, je reçois VolumeSerialNumber. Mais ce n'est pas unique. Si je formate le disque dur, cela va changer. Comment puis-je l'obtenir?

25
Joby

Hm, en regardant votre premier ensemble de code, je pense que vous avez récupéré (peut-être?) Le modèle de disque dur. Le numéro de série provient de Win32_PhysicalMedia.

Obtenir le modèle de disque dur

    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);
   }

Obtenir le numéro de série

 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;
   }

La source

J'espère que cela t'aides :)

32
Sprunth

J'ai utilisé la méthode suivante dans un projet et cela fonctionne avec succès.

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;
}

vous pouvez appeler la méthode ci-dessus comme mentionné ci-dessous,

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

Si vous avez besoin d'un identifiant unique, utilisez une combinaison de ces identifiants. 

11
Sency

Il y a un moyen simple pour la réponse de @ 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; }
}
7
huoxudong125

Utilisez la commande "vol" de Shell et analysez le numéro de série de sa sortie, comme ceci: . Fonctionne au moins dans 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;
                }
            }
        }
    }
3
Peksu

J'utilise ceci:

<!-- 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;
                }
            }
        }
0
Denis Ilyushchenko

Voici une solution utilisant win32 api et std string au cas où vous auriez besoin que votre application s'exécute sur un système d'exploitation sans CLR. Je l'ai trouvé ici sur 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;
}
0
IjonTichy

Ci-dessous une méthode entièrement fonctionnelle pour obtenir le numéro de série du disque dur:

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;
    }
0
Anjan Kant

Voici un code qui peut aider:

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);
0
Brahim Bourass

Le meilleur moyen que j'ai trouvé est de télécharger une dll depuis ici

Ajoutez ensuite la dll à votre projet.

Ensuite, ajoutez le code:

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

Ensuite, appelez l'ID du disque dur de l'endroit où vous en avez besoin

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

Remarque: accédez aux propriétés de la dll dans l'Explorateur et définissez "Action de génération" sur "Ressource intégrée".

0
Azhar Bandri