I need Unique Identifier of the system. I used processid but it also not unique for all PCs. So I get serial number of CPU.
I am using WMI to get serial number.
// Win32_CPU
var search = new ManagementObjectSearcher( "SELECT * FROM Win32_baseboard" );
var mobos = search.Get();
foreach (var m in mobos)
{
var serial = m["SerialNumber"]; // ProcessorID if you use Win32_CPU
}
But It returns "To be filled by O.E.M."
Why It does not returns exact serial number.
Please Let me know How can I Fix this.
I've needed to solve the same issue before.
Done the MAC address thing, that broke horribly as we quickly found several duplicates on just 10k users. We had problems to the day that product died.
Another project needed a similar solution and we tried the NTFS Id for C:\ drive. We threw out that idea and then considered the Win32 machine id, that of course also got thrown out.
Finally we settled onto the following: We created a Guid, encrypted it with the RSA machine key, and stuck it in the Registry.
I really believe that is your best bet for uniqueness even if you then need to incorporate some hardware information as well. So here is something like the code we used to store & fetch:
static class MachineKey
{
const byte[] ENTROPY = null;
const string KEY_PATH = @"HKEY_LOCAL_MACHINE\SOFTWARE\company-name-goes-here";
public static Guid Get()
{
try
{
string base64 = Microsoft.Win32.Registry.GetValue(KEY_PATH, "HostId", null) as string;
if (base64 == null)
return Create();
byte[] cypher = System.Convert.FromBase64String(base64);
byte[] bytes = System.Security.Cryptography.ProtectedData.Unprotect(cypher, ENTROPY,
System.Security.Cryptography.DataProtectionScope.LocalMachine);
if (bytes.Length != 20 || bytes[0] != 'H' || bytes[1] != 'o' || bytes[2] != 's' || bytes[3] != 't')
return Create();
byte[] guid = new byte[16];
Array.Copy(bytes, 4, guid, 0, 16);
return new Guid(guid);
}
catch
{
return Create();
}
}
static Guid Create()
{
byte[] prefix = new byte[] { (byte)'H', (byte)'o', (byte)'s', (byte)'t' };
Guid id = Guid.NewGuid();
byte[] store = new byte[20];
Array.Copy(prefix, store, 4);
Array.Copy(id.ToByteArray(), 0, store, 4, 16);
store = System.Security.Cryptography.ProtectedData.Protect(store, ENTROPY,
System.Security.Cryptography.DataProtectionScope.LocalMachine);
Microsoft.Win32.Registry.SetValue(KEY_PATH, "HostId", System.Convert.ToBase64String(store));
return id;
}
}
The OEM that assembled the computer never put in a serial number.
To fix it, you can build your own computer and put in the serial number correctly.
Did you try at Win32_BIOS
?
"I need Unique Identifier of the system."
A common approach is to use the MAC of a network card. It can be altered but for most purposes its good enough.
public PhysicalAddress GetMacAddress()
{
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up)
{
return nic.GetPhysicalAddress();
}
}
return null;
}
You could also try Win32_Processor, Win32_Bios or combination. By which I mean concat identifiers from several components of the system to generate a unique identifier for the system so it doesnt matter if for instance one of the component identifier isn't unique. This of course has the problem that if a component changes the unique identifier changes.