How to fast get Hardware-ID in C#?
Solution 1
For more details refer to this link
The following code will give you CPU ID:
namespace required 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;
}
For Hard disk ID and motherboard id details refer this-link
To speed up this procedure, make sure you don't use SELECT *
, but only select what you really need. Use SELECT *
only during development when you try to find out what you need to use, because then the query will take much longer to complete.
Solution 2
I got here looking for the same thing and I found another solution. If you guys are interested I share this class:
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
}
}
I won't take any credit for this because I found it here It worked faster than I expected for me. Without the graphic card, mac and drive id's I got the unique ID in about 2-3 seconds. With those above included I got it in about 4-5 seconds.
Note: Add reference to System.Management
.
Solution 3
The following approach was inspired by this answer to a related (more general) question.
The approach is to read the MachineGuid
value in registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
. This value is generated during OS installation.
There are few ways around the uniqueness of the Hardware-ID per machine using this approach. One method is editing the registry value, but this would cause complications on the user's machine afterwards. Another method is to clone a drive image which would copy the MachineGuid
value.
However, no approach is hack-proof and this will certainly be good enough for normal users. On the plus side, this approach is quick performance-wise and simple to implement.
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();
}
}
}
Related videos on Youtube
guaike
Updated on March 01, 2022Comments
-
guaike about 2 years
I need in my program to tie a license to a hardware ID. I tried use WMI, but it still slow.
I need, for example, CPU, HDD, and motherboard info.
-
CodesInChaos over 13 yearsSuch a licensing scheme sounds more like an annoyance to the honest customer than a deterrence to a cracker.
-
Vinod Srivastav almost 5 yearsPlease see the answer here stackoverflow.com/a/50907399/3057246
-
-
Jens about 14 yearsBe warned, though, that these ids are not neccesarily unique, or even existant. The processorID just identifies the processor design, the VolumeSerialnumber can be changed by the user and there are mainboard manufacturers that do not set a Serialnumber.
-
HotTester about 14 yearsThe best way to generate a unique id is to make a id by combination of all of these id's i.e. cpu id, motherboard id and hard disk id.
-
guaike about 14 yearsThank you for your reply,But i think WMI still slow,do you have any other way with out WMI
-
Garo Yeriazarian over 13 yearsYou say that WMI is slow, but how often do you run these checks? You only really need to check it at startup, then at random intervals from different places. If it's blocking your app, you can move the check to a background thread, just make sure you keep all the calls to the routines on the same thread and Dispose your objects appropriately (due to COM rules).
-
Fredrik over 10 yearsthe idea was to do it in C#
-
thelight about 10 years@ Frederic - The original post shows that the ID is needed for a security (license) system. However, the code provided in the answers is reading the info from MS Windows. It is piece-a-cake to modify that information. However, the Hardware ID Extractor DLL gets the information directly from the CPU (hardware level). You cannot change the hardware ID of a CPU (unless you melt the CPU and rebuild it :) )
-
thelight about 10 yearsAdditionally it gets the information in less than 1 microsecond. While retrieving info from MS Windows takes up to 5 seconds!
-
thelight about 10 yearsThe DLL presented below retrieves the information in less than 1 microsecond.
-
thelight about 10 yearsThe original post shows that the ID is needed for a security (license) system. However, the code provided in the answers is reading the info from MS Windows. It is piece-a-cake to modify that information. However, the Hardware ID Extractor DLL gets the information directly from the CPU (hardware level). You cannot change the hardware ID of a CPU (unless you melt the CPU and rebuild it :) )
-
thelight over 8 years@FredrikRedin - Can't C# import DLLs?
-
Roland almost 8 yearsNot always - permission wise
-
GDS almost 8 yearsI keep reading that there is no unique ID for processors (or any of the hardware) burned into the chips. How come this site claims that there is (and that they can retrieve it)?
-
Dan Is Fiddling By Firelight almost 7 yearsWin10 gives warning that this might not be safe. Combined with screenshots from a Samsung utility, and the AV safe images being self-hosted not coming from a third party I'm concerned that even if this was a legit company at one point it may have gone rogue.
-
Server Overflow almost 7 yearsThis is the scan from Google's VirusTotal.com. Only 3 (not-so-famous) antivirus products out of 62 shows a (false) positive alarm. All BIG (kaspersky, norton, panda, etc) av products shows the file clean. virustotal.com/en/file/…
-
ANeves over 6 yearsBenchmark: when my code uses
Select * From Win32_processor
it takes ~1s to run, when it usesSelect ProcessorId From Win32_processor
it takes ~0.01s! -
Majid Sabzalian over 6 yearsThis Code is Nice. Tnq
-
NSGaga-mostly-inactive over 6 yearsediting registry value is fast and
not necessarily produces problems on the user machine
- you can edit it, do what you want (in the s/w) and revert the value back. -
bh_earth0 almost 6 years1)Nice.. 2) will this still generate Same ID if i use this code 1 or 2 month later?. Will this exclude removable usb hdd, usb wifi adpter, virtual network card by virtualization softwares ??
-
Germán Martínez over 3 yearsAfter using this code for a while - there are issues: plugging in USB drives will change the key since it pulls info from any item with no empty value. Actually the whole identifier method is written badly and calling it multiple times for each property has to create the Management Class each time...
-
Lama over 3 yearsnot really useful, when you install bulk systems via OS images. You would have to manually set the GUID for each single machine.
-
LostPhysx about 3 yearsWill MaxClockSpeed change when it is overclocked?