2012-09-21 12 views
7

Pracuję nad aplikacją Metro napisaną w języku C# i potrzebuję sposobu na jednoznaczną identyfikację urządzenia. Znalazłem ASHWID w dokumentacji, która wygląda świetnie. Sugerowany kod jest następujący:Jak uzyskać unikatowy identyfikator komputera z systemem Windows 8 w języku C#?

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

Problem polega na tym, jak zmienić ten IBuffer w ciąg znaków, którego mogę użyć?

+1

Cytat: 'Jednakże, zmiany ASHWID jeśli profil sprzętowy zmian urządzeń, takich jak, gdy użytkownik odłączy Adapter USB Bluetooth ". http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx –

+0

Zauważyłem, że, ale wydaje się, że chodzi o najlepszą opcję dostępną w Windows 8. Dla naszych zastosowań wystarczy jeśli nie jest tak dobry, jak jesteśmy przyzwyczajeni! :) – StarlitSkies

Odpowiedz

12

Po wielu poszukiwaniach przy pomocy sugestii, które faktycznie znajdowały się w JS lub C++, w końcu znalazłem odpowiedź!

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

Dzięki iść do tego bloga - http://bartwullems.blogspot.co.uk/2012/09/windows-8-uniquely-identifying-device.html

+6

Zauważ, że ten id jest ** nie ** stały! Jeśli włączysz tryb samolotowy, otrzymasz inny identyfikator. –

+0

@ThomasLevesque Wierzę, że masz rację co do zmiany id podczas zmian w sprzęcie, ale po prostu próbowałem (UWP w Win10) i otrzymuję tę samą wartość z włączaniem i wyłączaniem trybu samolotowego i kiedy odłączam mysz, więc nie wydaje się tak wrażliwy, jak twierdzisz, przynajmniej na tej platformie. – ruffin

+0

@ruffin, zauważyłem, że w WinRT może to zmienić w UWP –

4

to powinno działać tak dobrze, ale nie mam do testowania Windows 8 z ...

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

A jeśli nazwać więcej niż raz, może chcesz, aby trzymać go w 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; 
} 

Albo po prostu mak e to statyczna, jeśli wiesz, że zawsze będzie się nazywać:

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

Niestety, "Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken (null) .Id.ToArray()" nie działa - nie ma metody "ToArray()" na IBuffer w Windows 8. – StarlitSkies

+0

I błagam o inne ... http://msdn.microsoft.com/en-us/library/hh582182.aspx –

+0

Cóż, jeśli skopiuję/wkleję twoją pierwszą sugestię do mojego projektu, otrzymuję ten błąd: "Windows.Storage.Streams.IBuffer" nie zawiera definicji "ToArray" i żadnej metody rozszerzenia "ToArray" akceptującej pierwszy można znaleźć argument typu "Windows.Storage.Streams.IBuffer". – StarlitSkies

3

Można użyć HardwareIdentification.GetPackageSpecificToken(null) patrz http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx

Funkcja ta daje wiele informacji, które można filtrować, jak chcesz. Na przykład:

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

jednak pamiętać, że ta funkcja, a podstawowa API, nie może zagwarantować absolutną niepowtarzalność we wszystkich komputerach podłączonych do internetu. Zazwyczaj łączysz to z informacjami o użytkowniku.

Inną opcją jest generowanie i przechowywanie identyfikatora GUID w pamięci lokalnej (bez roamingu) i używanie go jako identyfikatora urządzenia. W zależności od Twoich konkretnych potrzeb może to być lepsze rozwiązanie.

0

Dla GUID id można wykonać następujące czynności jako rozszerzenie powyższej odpowiedzi

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

To brzmi jak zły pomysł. Chodzi mi o to, co następuje: poszukaj pliku w pamięci lokalnej. Jeśli (i tylko jeśli) go tam nie ma, utwórz go i umieść tam nowy Guid, utworzony za pomocą Guid.NewGuid(). Użyj Guid jako swojego identyfikatora urządzenia. Przy następnym uruchomieniu wyjmij go z pliku. Zobacz https://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx –

Powiązane problemy