Как быстро получить Hardware-ID в C#?

Мне нужно в моей программе привязать лицензию к идентификатору оборудования. Я пытался использовать WMI, но это все еще медленно.

Мне нужна, например, информация о процессоре, жестком диске и материнской плате.

6 ответов

Решение

Для более подробной информации обратитесь к этой ссылке

Следующий код даст вам идентификатор процессора:

требуется пространство имен System.Management

var mbs = new ManagementObjectSearcher("Select ProcessorId From Win32_processor");
ManagementObjectCollection mbsList = mbs.Get();
string id = "";
foreach (ManagementObject mo in mbsList)
{
    id = mo["ProcessorId"].ToString();
    break;
}

Информацию об идентификаторе жесткого диска и идентификаторе материнской платы смотрите по этой ссылке

Чтобы ускорить эту процедуру, убедитесь, что вы не используете SELECT *, но только выберите то, что вам действительно нужно. использование SELECT * только во время разработки, когда вы пытаетесь выяснить, что вам нужно использовать, потому что тогда выполнение запроса займет гораздо больше времени.

Я пришел сюда в поисках того же и нашел другое решение. Если вы, ребята, заинтересованы, я поделюсь этим классом:

using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
    /// <summary>
    /// Generates a 16 byte Unique Identification code of a computer
    /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
    /// </summary>
    public class FingerPrint  
    {
        private static string fingerPrint = string.Empty;
        public static string Value()
        {
            if (string.IsNullOrEmpty(fingerPrint))
            {
                fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + 
            biosId() + "\nBASE >> " + baseId()
                            //+"\nDISK >> "+ diskId() + "\nVIDEO >> " + 
            videoId() +"\nMAC >> "+ macId()
                                     );
            }
            return fingerPrint;
        }
        private static string GetHash(string s)
        {
            MD5 sec = new MD5CryptoServiceProvider();
            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] bt = enc.GetBytes(s);
            return GetHexString(sec.ComputeHash(bt));
        }
        private static string GetHexString(byte[] bt)
        {
            string s = string.Empty;
            for (int i = 0; i < bt.Length; i++)
            {
                byte b = bt[i];
                int n, n1, n2;
                n = (int)b;
                n1 = n & 15;
                n2 = (n >> 4) & 15;
                if (n2 > 9)
                    s += ((char)(n2 - 10 + (int)'A')).ToString();
                else
                    s += n2.ToString();
                if (n1 > 9)
                    s += ((char)(n1 - 10 + (int)'A')).ToString();
                else
                    s += n1.ToString();
                if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
            }
            return s;
        }
        #region Original Device ID Getting Code
        //Return a hardware identifier
        private static string identifier
        (string wmiClass, string wmiProperty, string wmiMustBeTrue)
        {
            string result = "";
            System.Management.ManagementClass mc = 
        new System.Management.ManagementClass(wmiClass);
            System.Management.ManagementObjectCollection moc = mc.GetInstances();
            foreach (System.Management.ManagementObject mo in moc)
            {
                if (mo[wmiMustBeTrue].ToString() == "True")
                {
                    //Only get the first one
                    if (result == "")
                    {
                        try
                        {
                            result = mo[wmiProperty].ToString();
                            break;
                        }
                        catch
                        {
                        }
                    }
                }
            }
            return result;
        }
        //Return a hardware identifier
        private static string identifier(string wmiClass, string wmiProperty)
        {
            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;
        }
        private static string cpuId()
        {
            //Uses first CPU identifier available in order of preference
            //Don't get all identifiers, as it is very time consuming
            string retVal = identifier("Win32_Processor", "UniqueId");
            if (retVal == "") //If no UniqueID, use ProcessorID
            {
                retVal = identifier("Win32_Processor", "ProcessorId");
                if (retVal == "") //If no ProcessorId, use Name
                {
                    retVal = identifier("Win32_Processor", "Name");
                    if (retVal == "") //If no Name, use Manufacturer
                    {
                        retVal = identifier("Win32_Processor", "Manufacturer");
                    }
                    //Add clock speed for extra security
                    retVal += identifier("Win32_Processor", "MaxClockSpeed");
                }
            }
            return retVal;
        }
        //BIOS Identifier
        private static string biosId()
        {
            return identifier("Win32_BIOS", "Manufacturer")
            + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
            + identifier("Win32_BIOS", "IdentificationCode")
            + identifier("Win32_BIOS", "SerialNumber")
            + identifier("Win32_BIOS", "ReleaseDate")
            + identifier("Win32_BIOS", "Version");
        }
        //Main physical hard drive ID
        private static string diskId()
        {
            return identifier("Win32_DiskDrive", "Model")
            + identifier("Win32_DiskDrive", "Manufacturer")
            + identifier("Win32_DiskDrive", "Signature")
            + identifier("Win32_DiskDrive", "TotalHeads");
        }
        //Motherboard ID
        private static string baseId()
        {
            return identifier("Win32_BaseBoard", "Model")
            + identifier("Win32_BaseBoard", "Manufacturer")
            + identifier("Win32_BaseBoard", "Name")
            + identifier("Win32_BaseBoard", "SerialNumber");
        }
        //Primary video controller ID
        private static string videoId()
        {
            return identifier("Win32_VideoController", "DriverVersion")
            + identifier("Win32_VideoController", "Name");
        }
        //First enabled network card ID
        private static string macId()
        {
            return identifier("Win32_NetworkAdapterConfiguration", 
                "MACAddress", "IPEnabled");
        }
        #endregion
    }
}

Я не буду брать за это кредит, потому что нашел это здесь. Это сработало быстрее, чем я ожидал. Без графической карты, Mac и идентификаторов дисков я получил уникальный идентификатор примерно через 2-3 секунды. С учетом вышесказанного я получил его примерно за 4-5 секунд.

Следующий ответ был вдохновлен этим ответом на связанный (более общий) вопрос.

Подход заключается в том, чтобы прочитать MachineGuid значение в ключе реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, Это значение генерируется во время установки ОС.

Есть несколько способов обойти уникальность идентификатора оборудования для каждой машины, используя этот подход. Одним из методов является редактирование значения реестра, но впоследствии это может вызвать осложнения на компьютере пользователя. Другой метод заключается в клонировании образа диска, который будет копировать MachineGuid значение.

Тем не менее, ни один подход не является взломанным, и это, безусловно, будет достаточно для обычных пользователей. С другой стороны, этот подход быстр в производительности и прост в реализации.

public string GetMachineGuid()
{
   string location = @"SOFTWARE\Microsoft\Cryptography";
   string name = "MachineGuid";

   using (RegistryKey localMachineX64View = 
       RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
   {
       using (RegistryKey rk = localMachineX64View.OpenSubKey(location))
       {
           if (rk == null)
               throw new KeyNotFoundException(
                   string.Format("Key Not Found: {0}", location));

           object machineGuid = rk.GetValue(name);
           if (machineGuid == null)
               throw new IndexOutOfRangeException(
                   string.Format("Index Not Found: {0}", name));

           return machineGuid.ToString();
       }
   }
}

Мы используем комбинацию идентификатора процессора (ProcessorID) из Win32_processor и универсальный уникальный идентификатор (UUID) из Win32_ComputerSystemProduct:

ManagementObjectCollection mbsList = null;
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select ProcessorID From Win32_processor");
mbsList = mos.Get();
string processorId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
    processorId = mo["ProcessorID"] as string;
}

mos = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct");
mbsList = mos.Get();
string systemId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
    systemId = mo["UUID"] as string;
}

var compIdStr = $"{processorId}{systemId}";

Раньше мы использовали комбинацию: идентификатор процессора ("Select ProcessorID From Win32_processor") и серийный номер материнской платы ("SELECT SerialNumber FROM Win32_BaseBoard"), но потом выяснилось, что серийный номер материнской платы может быть не заполнен, а может быть заполнен единообразными значениями:

  • Заполняется OEM
  • Никто
  • Строка по умолчанию

Поэтому стоит учесть эту ситуацию.

Также имейте в виду, что ProcessorID номер может быть одинаковым на разных компьютерах.

Я переработал подход Алекса Суту, чтобы сделать код более быстрым и простым:

      using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Security.Cryptography;

namespace Test
{
    /// <summary>
    /// Generates a Guid based on the current computer hardware
    /// Example: C384B159-8E36-6C85-8ED8-6897486500FF
    /// </summary>
    public class SystemGuid
    {
        private static string _systemGuid = string.Empty;
        public static string Value()
        {
            if (string.IsNullOrEmpty(_systemGuid))
            {
                var lCpuId = GetCpuId();
                var lBiodId = GetBiosId();
                var lMainboard = GetMainboardId();
                var lGpuId = GetGpuId();
                var lMac = GetMac();
                var lConcatStr = $"CPU: {lCpuId}\nBIOS:{lBiodId}\nMainboard: {lMainboard}\nGPU: {lGpuId}\nMAC: {lMac}";
                _systemGuid = GetHash(lConcatStr);
            }
            return _systemGuid;
        }
        private static string GetHash(string s)
        {
            try
            {
                var lProvider = new MD5CryptoServiceProvider();
                var lUtf8 = lProvider.ComputeHash(ASCIIEncoding.UTF8.GetBytes(s));
                return new Guid(lUtf8).ToString().ToUpper();
            }
            catch (Exception lEx)
            {
                return lEx.Message;
            }
        }

        #region Original Device ID Getting Code
    
        //Return a hardware identifier
        private static string GetIdentifier(string pWmiClass, List<string> pProperties)
        {
            string lResult = string.Empty;
            try
            {
                foreach (ManagementObject lItem in new ManagementClass(pWmiClass).GetInstances())
                {
                    foreach (var lProperty in pProperties)
                    {
                        try
                        {
                            switch(lProperty)
                            {
                                case "MACAddress":
                                    if (string.IsNullOrWhiteSpace(lResult) == false)
                                        return lResult; //Return just the first MAC

                                    if (lItem["IPEnabled"].ToString() != "True")
                                        continue;
                                break;
                            }                                

                            var lItemProperty = lItem[lProperty];
                            if (lItemProperty == null)
                                continue;

                            var lValue = lItemProperty.ToString();
                            if (string.IsNullOrWhiteSpace(lValue) == false)
                                lResult += $"{lValue}; ";
                        }
                        catch { }
                    }

                }
            }
            catch{}
            return lResult.TrimEnd(' ', ';');
        }

        private static List<string> ListOfCpuProperties = new List<string>{ "UniqueId", "ProcessorId", "Name", "Manufacturer" };

        private static string GetCpuId()
        {
            return GetIdentifier("Win32_Processor", ListOfCpuProperties);
        }

        private static List<string> ListOfBiosProperties = new List<string> { "Manufacturer", "SMBIOSBIOSVersion", "IdentificationCode", "SerialNumber", "ReleaseDate", "Version" };
        //BIOS Identifier
        private static string GetBiosId()
        {
            return GetIdentifier("Win32_BIOS", ListOfBiosProperties);
        }

        private static List<string> ListOfMainboardProperties = new List<string> { "Model", "Manufacturer", "Name", "SerialNumber" };
        //Motherboard ID
        private static string GetMainboardId()
        {
            return GetIdentifier("Win32_BaseBoard", ListOfMainboardProperties);
        }

        private static List<string> ListOfGpuProperties = new List<string> { "Name" };
        //Primary video controller ID
        private static string GetGpuId()
        {
            return GetIdentifier("Win32_VideoController", ListOfGpuProperties);
        }

        private static List<string> ListOfNetworkProperties = new List<string> { "MACAddress" };
        private static string GetMac()
        {
            return GetIdentifier("Win32_NetworkAdapterConfiguration", ListOfNetworkProperties);
        }

        #endregion
    }
}

Вот DLL, которая показывает:
* Идентификатор жесткого диска (уникальный серийный номер оборудования, записанный в электронном чипе IDE)
* ID раздела (серийный номер тома)
* CPU ID (уникальный идентификатор оборудования)
* Производитель процессора
* Скорость процессора
* Теоретическая скорость процессора
* Загрузка памяти (общий объем используемой памяти в процентах (%))
* Total Physical (Общая физическая память в байтах)
* В наличии Physical (Физическая память оставлена ​​в байтах)
* Total PageFile (Общий файл страницы в байтах)
* Доступен PageFile (файл страницы оставлен в байтах)
* Total Virtual (Общий объем виртуальной памяти в байтах)
* Доступен Виртуальный (Виртуальная память оставлена ​​в байтах)
* Биос уникальный идентификационный номер BiosDate
* Биос уникальный идентификационный номер BiosVersion
* Биос уникальный идентификационный номер BiosProductID
* Bios уникальный идентификационный номер BiosVideo

(текст взят с оригинального сайта)
Работает с C#.

Другие вопросы по тегам