2012-09-21 24 views
7

Estoy trabajando en una aplicación de Metro escrita en C# y necesito una manera única de identificar un dispositivo. Encontré el ASHWID en la documentación que se ve genial. El código sugerido es el siguiente:¿Cómo obtengo un identificador único para una máquina que ejecuta Windows 8 en C#?

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

El problema es, ¿Cómo activo que IBuffer en una cadena que puedo usar?

+1

Cita: 'Sin embargo, los cambios ASHWID si el perfil de hardware del dispositivo cambia, como cuando el usuario desconecta una Adaptador USB Bluetooth'. http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx –

+0

Lo noté, pero parece ser la mejor opción disponible en Windows 8. Para nuestros usos será suficiente incluso si no es tan bueno como estamos acostumbrados! :) – StarlitSkies

Respuesta

12

Después de mucho buscar sugerencias que en realidad estaban en JS o C++ ¡finalmente encontré una respuesta!

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

Gracias ir a este blog - http://bartwullems.blogspot.co.uk/2012/09/windows-8-uniquely-identifying-device.html

+6

¡Tenga en cuenta que esta identificación no es ** constante **! Si enciendes el modo avión, obtienes una identificación diferente. –

+0

@ThomasLevesque Creo que tiene razón sobre el cambio de id cuando se realizan cambios en el hardware, pero lo intenté (UWP en Win10) y estoy obteniendo el mismo valor con el modo de avión activado o desactivado y cuando desconecto un mouse, por lo que no parece tan sensible como usted afirma aquí, al menos en esta plataforma. – ruffin

+0

@ruffin, noté que en WinRT, podría haber cambiado en UWP –

4

Esto debería funcionar tan bien, pero no tiene Windows 8 para probar con ...

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

Y si usted lo llama más de una vez, es posible que desee pegarlo en un 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; 
} 

O simplemente MAK e estática que si sabes que siempre se llamará:

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

Alas, "Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken (null) .Id.ToArray()" no funciona - no hay un método "ToArray()" en el IBuffer en Windows 8. – StarlitSkies

+0

I suplicar para diferir ... http://msdn.microsoft.com/en-us/library/hh582182.aspx –

+0

Bueno, si copio/pego su primera sugerencia en mi proyecto me sale este error: 'Windows.Storage.Streams.IBuffer' no contiene una definición para 'ToArray' y ningún método de extensión 'ToArray' aceptando una primera argumento de tipo 'Windows.Storage.Streams.IBuffer' podría ser encontrado. – StarlitSkies

3

Puede utilizar HardwareIdentification.GetPackageSpecificToken(null), ver http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx

Esa función le proporciona una gran cantidad de información, que puede filtrar a su gusto. Por ejemplo:

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

Sin embargo, tenga en cuenta que esta función, y la API subyacente, no pueden garantizar la unicidad absoluta en todas las máquinas conectadas a la Internet. Normalmente combinaría esto con información sobre el usuario.

Otra opción es generar y almacenar un GUID en almacenamiento local (no itinerante) y usarlo como su id. De máquina. Dependiendo de sus necesidades exactas, esta puede ser una mejor solución.

0

para un ID GUID se puede hacer lo siguiente como una extensión de la respuesta anterior

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); 
    } 
+0

Eso suena como una mala idea. Lo que quise decir es lo siguiente: busque un archivo en el almacenamiento local. Si (y solo si) no está allí, créelo y coloque un nuevo Guid allí, creado usando Guid.NewGuid(). Use ese Guid como su identificador de máquina. En la próxima ejecución, tómalo del archivo. Consulte https://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx –

Cuestiones relacionadas