如何获取在 C# 中运行 Windows 8 的机器的唯一标识符?
Posted
技术标签:
【中文标题】如何获取在 C# 中运行 Windows 8 的机器的唯一标识符?【英文标题】:How do I get a unique identifier for a machine running Windows 8 in C#? 【发布时间】:2012-09-13 17:42:36 【问题描述】:我正在开发一个用 C# 编写的 Metro 应用程序,需要一种方法来唯一地识别设备。我在文档中找到了看起来很棒的 ASHWID。建议的代码如下:
HardwareToken token = HardwareIdentification.GetPackageSpecificToken(null);
IBuffer hardwareId = token.Id;
IBuffer signature = token.Signature;
IBuffer certificate = token.Certificate;
问题是,我如何把那个 IBuffer 变成我可以使用的字符串?
【问题讨论】:
引用:However, the ASHWID changes if the hardware profile of the device changes, such as when the user unplugs a USB Bluetooth adapter
。 msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx
我确实注意到了这一点,但它似乎是 Windows 8 中可用的最佳选择。对于我们的使用来说,即使它不如我们习惯的那么好,它也足够了! :)
【参考方案1】:
经过大量寻找实际上是在 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
【讨论】:
请注意,这个 id 不是恒定的!如果你打开飞行模式,你会得到一个不同的 ID。 @ThomasLevesque 我相信您对硬件进行更改时的 id 转移是正确的,但我刚刚尝试过(Win10 中的 UWP)并且在打开或关闭飞行模式以及何时获得相同的值我拔掉了鼠标,所以它看起来不像你在这里所说的那么敏感,至少在这个平台上是这样。 @ruffin,我注意到在 WinRT 中,它可能在 UWP 中发生了变化 如果您将互联网连接从 Wi-Fi 切换到以太网或相反,此 token.Id 值会发生变化。所以,它不是独一无二的。至少在 Win 8.1 中【参考方案2】:这应该也可以,但我没有要测试的 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()));
【讨论】:
唉,“Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null).Id.ToArray()”不起作用 - Windows 8 中的 IBuffer 上没有“ToArray()”方法。 好吧,如果我将您的第一个建议复制/粘贴到我的项目中,我会收到此错误:“Windows.Storage.Streams.IBuffer”不包含“ToArray”的定义并且没有扩展方法“ToArray” ' 可以找到接受“Windows.Storage.Streams.IBuffer”类型的第一个参数。 您需要添加适当的 using 语句 -using System.Runtime.InteropServices.WindowsRuntime
并且您必须拥有 .NET 4.5
添加 using 语句似乎确实有效,但有点奇怪的是,Visual Studio 不想建议像通常在我键入需要新 using 语句的内容时那样解决问题!
@StarlitSkies - 我发现 VS2010 中不建议扩展,例如 Linq 扩展。【参考方案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。根据您的具体需求,这可能是一个更好的解决方案。
【讨论】:
【参考方案4】:对于 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);
【讨论】:
这听起来是个坏主意。我的意思是:在本地存储中查找文件。如果(且仅当)它不存在,创建它并在其中放置一个新的 Guid,使用 Guid.NewGuid() 创建。使用该 Guid 作为您的机器标识符。在下一次运行时,从文件中获取它。见msdn.microsoft.com/en-us/library/system.guid.newguid.aspx以上是关于如何获取在 C# 中运行 Windows 8 的机器的唯一标识符?的主要内容,如果未能解决你的问题,请参考以下文章
如何获取方法异步 c# windows phone 8.1 的值
如何在 UWP 应用(C# 或 WinJS)中获取 Windows 10 版本(例如 1809、1903、1909、...)?
.NET Framework 4 桌面应用程序 [C#] 将运行 Windows 8、8.1 和 10