如何在 Windows 10 周年更新中获取唯一设备 ID

How to get unique Device IDs on Windows 10 Anniversary Update

Windows 10 的先前迭代具有 HardwareToken API (aka ASHWID) 来获取设备的唯一标识符,但它有几个缺点:

周年纪念更新中是否有新方法来获得更有用/稳定的 ID,该 ID 在所有 Windows 10 个平台上保持一致?我想在我的应用程序中使用 ID 来关联来自同一设备的遥测数据,以用于使用指标和广告。我不会将该值用于识别用户、创建匿名帐户、加密数据或任何其他类似的事情。它只会用于遥测目的。

我想做类似的事情:

var id = Windows.Something.GetDeviceId();  // hypothetical OS function
var telemetry = MyApp.GetUsageTelemetry(); // my own function

// Use (eg) HttpClient to send both id and telemetry to my 
// cloud infrastructure for processing and correlation
SendDataToCloudForProcessing(id, telemetry)

Updated Nov 3rd 2017 (new Registry value, below)

Windows 10 周年更新引入了新的 SystemIdentification type,它完全可以满足您的需求。它比旧的 ASHWID 有几个好处:

  • 它在所有 Windows 10 个平台上可用
    • 注意:ASHWID 现在也可以在所有平台上使用,但仍然存在上面列出的其他缺点
  • 它 return 是一个稳定值(即使在 PC 上),不会因硬件升级或重新安装 OS
  • 而改变
  • 它return是同一发行商的所有应用程序的相同值,允许您的应用程序组合之间的关联
  • 它还可以 return 一个在 所有 应用程序中相同的值,对于特定用户,如果您有 userSystemInfo Restricted Capability
    • 注意:这对企业场景最有用;您不太可能在没有充分理由的情况下为 Windows 商店批准使用此功能的应用程序,因为它代表隐私问题

API 有一个小缺点:它无法在某些旧 PC 上运行,因为它需要 UEFI 或 TPM。过去 5 年以上制造的大多数 PC 都应该有这个硬件,所有其他非 PC 设备(phone、Xbox、HoloLens 等)都有正确的硬件。如果您发现一台 PC 没有硬件,您将需要回退到 ASHWID 或其他一些机制。

2017 年 11 月 3 日更新

从 Windows Fall Creator's Update(又名 1709 或 RS3 或通用 API 合同 5)开始,a new Registry identification source 提供了一个相对稳定的 ID,以防用户不这样做没有合适的硬件。如果用户重新安装 OS(不是升级,而是新安装)或者用户更改注册表,它将发生变化,但在其他方面与 UefiTmp

2017 年 11 月 3 日结束更新

使用API很简单;不需要在后端进行复杂的解析或计算漂移:

using Windows.System.Profile;

IBuffer GetSystemId()
{
  // This sample gets the publisher ID which is the same for all apps
  // by this publisher on this device.
  // Use GetSystemIdForUser if you have the userSystemId capability
  // and need the same ID across all apps for this user (not 
  // really applicable for apps in the Windows Store)
  var systemId = SystemIdentification.GetSystemIdForPublisher();

  // Make sure this device can generate the IDs
  if (systemId.Source != SystemIdentificationSource.None)
  {
    // The Id property has a buffer with the unique ID
    return systemId.Id;
  }

  // This is a very old PC without the correct hardware. Use 
  // another mechanism to generate an ID (or perhaps just give 
  // up due to the small number of people that won't have the ID; 
  // depends on your business needs).
  return GetIdFromAshwidOrSomethingElse();
}

如问题中所述,此 ID 只能用于后端服务中的关联(例如,用于遥测、广告、使用指标等)。它不应用于创建匿名用户帐户、识别或跟踪用户、加密用户数据等。 这是因为不同的用户可以共享同一设备,或者同一用户可以在不同的设备之间漫游,因此 ID 不会将 1:1 映射到用户或其数据。

此 API 在通用 API 合同 v3 中可用,并且可以在 Windows 通用 SDK 版本 10.0.14393.0 中找到(请记住,如果您正在做多-version 应用程序并希望点亮此 API 的用法,您应该 而不是 进行运行时版本检查;相反,您应该 query the OS to see if the API is available).