MatthewKing / DeviceId

A simple library providing functionality to generate a 'device ID' that can be used to uniquely identify a computer.
MIT License
729 stars 118 forks source link

Wrong ProcessorId and MotherboardSerialNumber #4

Closed OrihuelaConde closed 5 years ago

OrihuelaConde commented 5 years ago

I'm getting "To be filled by O.E.M..BFEBFBFF000306A9" by executing:

var t = new DeviceIdBuilder().AddProcessorId().AddMotherboardSerialNumber().UseFormatter(new StringDeviceIdFormatter(new PlainTextDeviceIdComponentEncoder())).ToString();

I've tested the same code in other computer with the same result.

Here is my System Information, if its helps.

imagen

Visual Studio 2017 15.8.5 .NET Framework 4.6.1

MatthewKing commented 5 years ago

Hi,

This looks about right.

The processor ID is derived from the Win32_Processor WMI class. As seen in your system information screenshot, a few of the fields are just returning 'To be filled by O.E.M'. DeviceId can only go on what is actually returned by SMBIOS.

The motherboard serial number is derived from the Win32_BaseBoard WMI class. The serial number is assigned by the manufacturer, and DeviceId is just returning that value. These values may or may not be unique, depending on what the manufacturer chooses to do when assigning serial numbers.

So, the values you are seeing are "correct", in that they are returning the right values. Unfortunately, your particular machine doesn't have very useful information in those values.

If you're trying to get a guaranteed unique device ID, I recommend adding a few more fields to your device ID. You could consider AddMacAddress, or AddFileToken. The more fields you use, the better chance of generating a device ID that is truly unique across all systems. You could even build a custom component that uses some other WMI classes.

OrihuelaConde commented 5 years ago

Thank you, using "AddMacAddress" return all the MAC Addresses (including virtual ones), also this is not viable because a MAC Address can be "altered". I prefer to use something more unique, like the Serial Number of the System Disk Drive. I ended with this solution, if you want to add to your code:

.AddComponent(new DeviceIdComponent("SystemDriveSerialNumber", GetSystemDrive))

private string GetSystemDrive()
        {
            // Get the system logical disk id (drive letter)
            string systemLogicalDiskDeviceId = Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 2);

            // Start by enumerating the logical disks
            using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk WHERE DeviceID='" + systemLogicalDiskDeviceId + "'"))
            {
                foreach (ManagementObject logicalDisk in searcher.Get())
                    foreach (ManagementObject partition in logicalDisk.GetRelated("Win32_DiskPartition"))
                        foreach (ManagementObject diskDrive in partition.GetRelated("Win32_DiskDrive"))
                            return diskDrive["SerialNumber"].ToString();
            }

            return string.Empty;
        }

Source

MatthewKing commented 5 years ago

Awesome, glad you came up with a solution.

Using the serial number of the system disk drive is a great idea. I'll look into adding functionality like that to the library. Hopefully next weekend when I have some free time.

Thanks!