UDID

In my previsious post (How do I get a Unique Identifier for a Device within Windows 10 Universal?) I talked about how getting a unique Id for a device. I’ve found another way.

In the registry there is an unique ID generated during Windows installation and it won't change until you reinstall Windows. You can find such ID in HKLM/Software/Microsoft/Cryptography, it's a string named MachineGuid.

If you can identify a component you're pretty sure that won't change (motherboard for example) you may use a simple WMI query to get its serial number but you should always provide a fallback because many many MBs returns a fake S/N (and virtual machines may returns always the same one). What's the proper solution...well it depends on what you have to do with that ID. Identify the user? Check for license? Encrypt data? Each of these has a different "best practice" for ID.

Get an unique ID for the device
If you have to identify a particular device (regardless to the user) you have many options, what I'd prefer to do is to generate an ID using only stable data (S/N from motherboard and BIOS, for example). This won't help you if he/she completely renew its hardware but it should be stable enough (but you have to define what is enough in your case). You may even use the S/N of the primary disk (with portable devices it's pretty stable and you may even use it in combination with other serial numbers to build your own ID). You can get this informations through WMI or (if you're targeting WinRT) through specific bytes of the ASHWID structure.

Encrypt data
In this case you have to think when data may be unrecoverable. If with a small hardware change your users won't be able to read their previous files well, they'll be unhappy. In this case I would suggest to use the MachineGuid, unless they reinstall the OS they wouldn't have to worry (but do them a favor and provide a way to read back that GUID somewhere). If you're sure you're targeting a portable device like a phone or a tablet then disk serial number (or CPU ID, if available, or MB or BIOS) may be appropriate too (because it's pretty uncommon they'll change).

Licensing
I would use a combination of many (stable) IDs. As for an unique identifier for the device you can't be sure nothing will change. In the past MAC address was vastly used for this but mobile devices changed these rules (because it's easy to turn off a NIC). You can still use them but you have to put extra care (and code) to manage that situation. Again a combination of multiple IDs (chosen carefully) can help you to minimize customers effort when they change their hw/sw setup. In this case a good compromise could be the OS serial number (not the MachineGuid). If they install a new OS then they have to update your license too (but I would use it combined with something else to be sure they won't use the same OS copy on multiple computers or virtual machines).

Note about virtual machines
If you have to target VMs too then things become more complicated. In theory an user can create multiple copies of the same VM with exactly the same hardare and software configuration. If this is an issue and if you can't address this properly (for example using a network check) I would suggest you don't support them at all (just quit if you detect a VM).

/// 
/// Here is a code example that filters form ASHWID the hardware modules
/// that are unlikely to be changed (CPU id, size of memory, serial number of the disk device and bios)
/// 
/// 
public string GetDeviceID()
{
    // get the hardware Profile id and convert it to byte Array
    var hardwareToken = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);

    byte[] byteArray = null;
    Windows.Security.Cryptography.CryptographicBuffer.CopyToByteArray(hardwareToken.Id, out byteArray);

    var deviceSerial = "";
    var offset = 0;

    // we filter the hardware modules that are unlikely to be changed, and aggregate them to a string.
    while (offset < hardwareToken.Id.Length)
    {
        // CPU ID of the processor || Size of the memory || Serial number of the disk device || BIOS
        if ((byteArray[offset] == 1 || byteArray[offset] == 2 || byteArray[offset] == 3 || byteArray[offset] == 9) && byteArray[offset + 1] == 0)
        {
            for (var i = 0; i < 4; i++)
            {
                deviceSerial += byteArray[offset + i].ToString();
            }
        }
        offset += 4;
    }

    return deviceSerial;
}

 

Happy coding!

How do I get a Unique Identifier for a Device within Windows 10 Universal?

If you google a bit about this problem, you can’t find a right solution because all people are speaking about Hardware Token. Unfortunately this functionality doesn’t exists for Universal Windows Application.

There are at the moment only a way. You have to add the Extension reference "Windows Desktop Extensions for the UWP" or "Windows Mobile Extensions for the UWP", then you can use the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.ExchangeActiveSyncProvisioning;
using Windows.System.Profile;

namespace PSC.Code
{
    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!");
        }
    }
}

 

Someone speaks about to use EasClientDeviceInformation provides a unique Id but this is working only for Windows Store Apps.

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

 

Happy coding!

Advertsing

125X125_06


Subscribe to our mailing list

* indicates required


TagCloud

MonthList

CommentList