Как получить уникальный идентификатор для машины под управлением Windows 8 в C#?

Я работаю над приложением Metro, написанным на C#, и мне нужен способ уникальной идентификации устройства. Я нашел ASHWID в документации, которая выглядит великолепно. Предлагаемый код выглядит следующим образом:

HardwareToken token = HardwareIdentification.GetPackageSpecificToken(null);
IBuffer hardwareId = token.Id;
IBuffer signature = token.Signature;
IBuffer certificate = token.Certificate;

проблема в том, как превратить этот IBuffer в строку, которую я могу использовать?

4 ответов


после большой охоты через предложения, которые были на самом деле в JS или C++, я наконец нашел ответ!

private string GetHardwareId()  
{  
    var token = HardwareIdentification.GetPackageSpecificToken(null);  
    var hardwareId = token.Id;  
    var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);  

    byte[] bytes = new byte[hardwareId.Length];  
    dataReader.ReadBytes(bytes);  

    return BitConverter.ToString(bytes);  
}  

Спасибо этот блог - http://bartwullems.blogspot.co.uk/2012/09/windows-8-uniquely-identifying-device.html


это должно работать, но у меня нет Windows 8 для тестирования...

private string GetHardwareId()   
{ 
  return BitConverter.ToString(Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray());
}

и если вы называете его более одного раза, вы можете вставить его в Lazy<T>

private static Lazy<string> _hardwareId = new Lazy<string>(() => BitConverter.ToString(Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray()), true);

public string HardwareId()   
{ 
     return _hardwareId.Value;
}

или просто сделайте его статическим, если вы знаете, что он всегда будет называться:

public static readonly string HardwareId = BitConverter.ToString(Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray()));

можно использовать HardwareIdentification.GetPackageSpecificToken(null) см. http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx

эта функция дает вам много информации, которую вы можете фильтровать, как вам нравится. Например:

public static string GetMachineId()
{
    var hardwareToken = 
        HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray();
    var count = hardwareToken.Length / 4;
    ulong id = 0ul;
    for (int i = 0; i < count; i++)
    {
        switch (BitConverter.ToUInt16(hardwareToken, i * 4))
        {
            case 1:
                // processor
            case 2:
                // memory
            case 9:
                // system BIOS
                id = (id << 12) ^ BitConverter.ToUInt16(hardwareToken, i * 4 + 2);
                break;
        }
    }
    return Convert.ToBase64String(BitConverter.GetBytes(id));
}

однако имейте в виду, что эта функция и базовый API не могут гарантировать абсолютную уникальность на всех машинах, подключенных к интернету. Обычно вы объединяете это с информацией о пользователь.

другой вариант-создать и сохранить идентификатор GUID в локальном (не перемещаемом) хранилище и использовать его в качестве идентификатора компьютера. В зависимости от ваших точных потребностей это может быть лучшим решением.


для идентификатора guid вы можете сделать следующее в качестве расширения вышеуказанного ответа

    private Guid GetHardwareId()
    {
        var token = HardwareIdentification.GetPackageSpecificToken(null);  
        var hardwareId = token.Id;  
        var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(hardwareId);  

        byte[] bytes = new byte[hardwareId.Length];  
        dataReader.ReadBytes(bytes);  

        byte[] deviceId = new byte[16];
        Array.Copy((byte[])bytes, deviceId, deviceId.Length);

        return new Guid(deviceId);
    }