如何获取系统的唯一标识符

时间:2010-09-29 15:55:02

标签: c# wmi

我需要系统的唯一标识符。我使用了processid,但它并非所有PC都独一无二。所以我得到了CPU的序列号。

我正在使用WMI获取序列号。 // 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
}

但它返回“由O.E.M填充

为什么它不会返回确切的序列号。

请告诉我如何解决此问题。

4 个答案:

答案 0 :(得分:4)

我之前需要解决同样的问题。

完成了MAC地址的事情,因为我们很快就在10k用户身上发现了几个副本,因此破坏了。我们在产品死亡的那天遇到了问题。

另一个项目需要一个类似的解决方案,我们尝试使用NTFS Id for C:\ drive。我们抛弃了这个想法,然后考虑了Win32机器ID,当然也被抛弃了。

最后我们解决了以下问题:我们创建了一个Guid,使用RSA机器密钥对其进行了加密,并将其粘贴在注册表中。

我真的相信即使您需要合并一些硬件信息,这也是您唯一的最佳选择。所以这就像我们用来存储的代码一样。取:

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;
    }
}

答案 1 :(得分:3)

组装计算机的OEM从未输入序列号。

要修复它,您可以构建自己的计算机并正确输入序列号。

答案 2 :(得分:0)

您是否尝试过Win32_BIOS

答案 3 :(得分:0)

“我需要系统的唯一标识符。”

常见的方法是使用网卡的MAC。它可以改变,但在大多数情况下它足够好。

public PhysicalAddress GetMacAddress()
{
    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (nic.OperationalStatus == OperationalStatus.Up)
        {
            return nic.GetPhysicalAddress();
        }
    }

    return null;
}

您也可以尝试Win32_Processor,Win32_Bios或组合。我指的是来自系统的几个组件的concat标识符,以生成系统的唯一标识符,因此,如果组件标识符之一不是唯一的则无关紧要。这当然有一个问题,即如果组件更改了唯一标识符的更改。