如何在C#中快速获取硬件ID?
我需要在我的程序中将许可证绑定到硬件ID。 我尝试过使用WMI,但仍然很慢。
例如,我需要CPU,硬盘和主板信息。
欲了解更多详情,请参阅此链接
下面的代码会给你CPU ID:
命名空间需要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; }
有关硬盘ID和主板ID的详细信息,请参阅此链接
为了加快这个过程,确保你不使用SELECT *
,而只select你真正需要的东西。 只有在开发过程中,当您尝试找出需要使用的内容时才使用SELECT *
,因为这样查询将花费更长的时间才能完成。
我到了这里寻找同样的东西,我find了另一个解决scheme。 如果你们有兴趣,我可以分享这个课程:
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 } }
我不会因此而感到失望,因为我在这里发现它比我预期的要快。 没有graphics卡,MAC和驱动器ID的我在2-3秒左右得到了唯一的ID。 以上包括我在4-5秒左右。
下面的方法是从这个问题的答案中得到灵感的。
该方法是读取registry项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
的MachineGuid
值。 该值在安装操作系统期间生成。
使用这种方法每台机器的硬件ID的唯一性方法很less。 一种方法是编辑registry值,但这会在用户的机器上造成复杂的后果。 另一种方法是克隆将复制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(); } } }
这是一个DLL,显示:
*硬盘驱动器ID(驱动器IDE电子芯片中写入的唯一硬件序列号)
*分区ID(卷序号)
* CPU ID(唯一的硬件ID)
* CPU供应商
* CPU运行速度
* CPU理论速度
*内存负载(使用的总内存百分比(%))
*物理总数(以字节为单位的总物理内存)
*可用物理(以字节为单位的物理内存)
*总PageFile(总页数文件以字节为单位)
*可用PageFile(页面文件留在字节中)
*虚拟总数(虚拟内存总字节数)
*可用虚拟(以字节为单位的虚拟内存)
* Bios唯一标识号BiosDate
* Bios独特的识别号码BiosVersion
* Bios唯一标识号BiosProductID
* Bios独特的识别号码BiosVideo
(从原始网站抓取文本)
它适用于C#。
这个代码不工作,直到你遵循这个步骤
将引用添加到System.Management程序集。
为此你必须这样做:
-
转到项目选项卡
-
点击添加引用
-
点击.NET选项卡
-
selectSystem.Management并按下确定