如何在Windows 10通用平台上获取设备的唯一标识符?

23

这是我旧的实现方式,用于获取Windows通用8.1的唯一设备ID,但是HardwareIdentification类型不再存在。

    private static string GetId()
    {
        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).Replace("-", "");
    }

FYI,在周年更新版中有一种更好的方法。 - Peter Torr - MSFT
这个硬件ID在Windows中是否可以看到,可能是通过命令行或设置界面?我是说这个硬件ID实际上在哪里显示出来。 - Jins Peter
5个回答

20

这是Windows桌面的完整解决方案:

  • 像Peter Torr - MSFT提到的那样,添加扩展引用“Windows Desktop Extensions for the UWP”。

使用此代码获取HardwareId:

using System;
using Windows.Security.ExchangeActiveSyncProvisioning;
using Windows.System.Profile;

namespace Tobit.Software.Device
{
    public sealed class DeviceInfo
    {
        private static DeviceInfo _Instance;
        public static DeviceInfo Instance
        {
            get {
                if (_Instance == null)
                    _Instance = new DeviceInfo();
                return _Instance; }

        }

        public string Id { get; private set; }
        public string Model { get; private set; }
        public string Manufracturer { get; private set; }
        public string Name { get; private set; }
        public static string OSName { get; set; }

        private DeviceInfo()
        {
            Id = GetId();
            var deviceInformation = new EasClientDeviceInformation();
            Model = deviceInformation.SystemProductName;
            Manufracturer = deviceInformation.SystemManufacturer;
            Name = deviceInformation.FriendlyName;
            OSName = deviceInformation.OperatingSystem;
        }

        private static string GetId()
        {
            if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.System.Profile.HardwareIdentification"))
            {
                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).Replace("-", "");
            }

            throw new Exception("NO API FOR DEVICE ID PRESENT!");
        }
    }
}

有没有想法……如果你要构建一个同时在手机和桌面上使用的UWP应用或库,你能同时使用手机和桌面的SDK吗?这样做会导致构建、运行时或认证方面出现问题吗? - Filip Skakun
如果您在计算机上添加了RAM,硬件令牌会发生变化,对吗? - Grigory
@Grigory 我相信是这样的,我记得在 MSDN 上看到过类似的内容,即在生成令牌时会考虑 CPU ID 和 RAM 大小。 - terry
1
@El 我在同一设备上获取到了不同的硬件ID。 - Kinjan Bhavsar
@KinjanBhavsar 对于多个应用程序来说,这是一种预期的行为。你在谈论什么上下文? - Jens Marchewka
显示剩余3条评论

9

Windows 1609升级(“周年更新”)

请参阅此问答以获取更好的ID获取方式。

旧操作系统版本的旧信息

您需要添加桌面和/或移动SDK的引用以构建针对硬件令牌的应用程序。在运行时,应使用ApiInformation类型查询API是否存在,然后再使用它(其他设备系列如Xbox没有该API)。

尽管如此,很多时候当人们要求设备ID时,这并不是解决问题的最佳方案——您确定需要在整个生命周期内标识物理设备,即使所有权发生变化吗?


2
不,我只需要一种唯一的ID来识别APP上的设备,以便于锁定APP的某些功能。同时,将该用户(聊天)的推送URI与我们的数据库关联起来。 - Jens Marchewka
3
这正是我们所不希望的。因为您可以创建新账户再次滥用我们的服务。 - Jens Marchewka
1
当客户将设备卖给其他人时,您该怎么办?现在他们与错误的帐户相关联。 - Peter Torr - MSFT
1
如果设备重置后ID发生变化,则您的方法将无效(Bob被禁止;Bob重置设备;Bob被解禁)。 - Peter Torr - MSFT
1
硬件令牌可以使用,只要您有对设备交给另一个用户时进行缓解的措施。如果您只禁止DoS类型攻击(在短时间窗口内),那就可以了。 - Peter Torr - MSFT
显示剩余13条评论

8
似乎是这样的:

var deviceInformation = new EasClientDeviceInformation();
string Id = deviceInformation.Id.ToString();

“doing the magic”指的是EasClientDeviceInformation,它提供了一个唯一的Id。

Id属性使用从MachineID、User SID和Package Family Name的SHA256哈希的前16个字节截断的GUID表示DeviceId,其中MachineID使用本地用户组的SID。

但是它仅适用于Windows Store应用程序...因此必须有另一种解决方案。


EasClient ID 不是适合此问题的正确解决方案。它也不适用于所有设备系列,因此您需要引用扩展 SDK。 - Peter Torr - MSFT
嗨@EI Marchewko,EasClientDeviceInformation在Windows Phone 10上可以使用吗? - Kishor Bikram Oli

1
//you can use this
//its working with me very fine on windows 10
//replace the word bios with any hardware name you want
//data also can be found with using windows application named (wbemtest) 

using System.Management;
public static async Task<string> ReturnHardWareID()
        {
            string s = "";
            Task task = Task.Run(() =>
            {
                ManagementObjectSearcher bios = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS");
                ManagementObjectCollection bios_Collection = bios.Get();
                foreach (ManagementObject obj in bios_Collection)
                {
                    s = obj["SerialNumber"].ToString();
                    break; //break just to get the first found object data only
                }
            });
            Task.WaitAll(task);

            return await Task.FromResult(s);
        }

1
EasClientDeviceInformation在Windows 10移动版中无法使用。设备ID对于每个手机都是相同的(我们所有的win10m客户端都使用相同的GUID进行注册)。我们需要该ID以将推送消息发送到正确的手机。

我们有解决方案吗?EasClientDeviceInformation为所有手机提供相同的ID。 - Neena

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接