2012-09-21 25 views
7

我正在使用C#編寫的Metro應用程序,並且需要一種唯一標識設備的方法。我在文檔中發現了ASHWID,看起來不錯。建議的代碼如下:如何獲得在C#中運行Windows 8的計算機的唯一標識符?

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

的問題是,我怎麼把那IBuffer成字符串,我可以使用?

+1

引用:'但是,ASHWID變化如果設備的變化,當用戶拔掉一個諸如硬件配置文件USB藍牙適配器「。 http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx –

+0

我注意到,但它似乎是關於Windows 8中可用的最佳選項。對於我們的使用它甚至可以滿足如果它不如我們習慣的那麼好! :) – StarlitSkies

回答

12

經過很多狩獵,通過實際上在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

+6

請注意,此ID是**不是**不變!如果您打開飛行模式,您會得到一個不同的ID。 –

+0

@ThomasLevesque我相信你對硬件進行改變時的ID轉換是正確的,但我只是嘗試過(UWP在Win10中),並且在開啓或關閉飛行模式時獲得相同的值,當我拔下鼠標時,似乎並不像你在這裏聲稱的那樣敏感,至少在這個平臺上。 – ruffin

+0

@ruffin,我注意到,在WinRT中,它可能會在UWP –

4

這應該工作一樣好,但我沒有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; 
} 

或者只是mak Ë它靜若你知道它會一直被稱爲:

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

唉,「Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray()」不起作用 - 在Windows 8中的IBuffer上沒有「ToArray()」方法。 – StarlitSkies

+0

I乞求不同... http://msdn.microsoft.com/en-us/library/hh582182。ASPX –

+0

好吧,如果我複製/你的第一個建議粘貼到項目中,我得到這個錯誤: 「Windows.Storage.Streams.IBuffer」不包含一個定義爲「ToArray的」,沒有擴展方法「ToArray的」接受第一可以找到類型爲「Windows.Storage.Streams.IBuffer」的參數。 – StarlitSkies

3

您可以使用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,並將其用作機器ID。根據你的具體需求,這可能是一個更好的解決方案。

0

對於一個GUID ID,你可以做以下的一個擴展上面的回答

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

這聽起來像個壞主意。我的意思是以下內容:在本地存儲中查找文件。如果(且僅當)不存在時,創建它並在其中放置一個新Guid,並使用Guid.NewGuid()創建。使用該Guid作爲您的機器標識符。在下一次運行中,從文件中取出它。請參閱https://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx –

相關問題