Giter VIP home page Giter VIP logo

deviceid's Introduction

DeviceId

A simple library providing functionality to generate a 'device ID' that can be used to uniquely identify a computer.

Quickstart

What packages are needed?

As of version 6, the packages have been split up so that users can pick-and-choose what they need, without having to pull down unnecessary references that they won't use:

  • The main DeviceId package contains the core functionality and a number of cross-platform components.
  • The DeviceId.Windows package adds a few Windows-specific components.
  • The DeviceId.Windows.Wmi package adds even more Windows-specific components, using WMI.
  • The DeviceId.Windows.WmiLight package adds the same components as above, but using WmiLight instead of WMI.
  • The DeviceId.Windows.Mmi package adds the same components as above, but using MMI instead of WMI for those instances where WMI isn't appropriate (such as where no .NET Framework is present on the machine).
  • The DeviceId.Linux package adds a few Linux-specific components.
  • The DeviceId.Mac package adds a few Mac-specific components.
  • The DeviceId.SqlServer package adds support for generating a database ID for SQL Server databases.

You can pick-and-choose which packages to use based on your use case.

For a standard Windows app, the recommended packages are: DeviceId and DeviceId.Windows. If you want some extra advanced components you can also add DeviceId.Windows.Wmi.

PM> Install-Package DeviceId
PM> Install-Package DeviceId.Windows

Building a device identifier

Use the DeviceIdBuilder class to build up a device ID.

Here's a Windows-specific device ID, using the DeviceId.Windows package to get the built-in Windows Device ID.

string deviceId = new DeviceIdBuilder()
    .OnWindows(windows => windows.AddWindowsDeviceId())
    .ToString();

Here's a simple cross-platform one, using only the DeviceId package, which is valid for both version 5 and version 6 of the library:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .AddFileToken("example-device-token.txt")
    .ToString();

Here's a more complex device ID, making use of some of the advanced components from the DeviceId.Windows.Wmi (or DeviceId.Windows.Mmi) package:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .OnWindows(windows => windows
        .AddProcessorId()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber())
    .ToString();

Here's a complex cross-platform device ID, using DeviceId.Windows.Wmi, DeviceId.Linux, and DeviceId.Mac:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .OnWindows(windows => windows
        .AddProcessorId()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber())
    .OnLinux(linux => linux
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber())
    .OnMac(mac => mac
        .AddSystemDriveSerialNumber()
        .AddPlatformSerialNumber())
    .ToString();

You can also generate a unique identifier for a database instance. Currently, only SQL Server is supported, but more may be added if there is demand and/or community support:

using SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string databaseId = new DeviceIdBuilder()
    .AddSqlServer(connection, sql => sql
        .AddServerName()
        .AddDatabaseName()
        .AddDatabaseId())
    .ToString();

What can you include in a device identifier

The following extension methods are available out of the box to suit some common use cases:

From DeviceId:

  • AddUserName adds the current user's username to the device identifer.
  • AddMachineName adds the machine name to the device identifier.
  • AddOsVersion adds the current OS version to the device identifier. Note: This uses Environment.OSVersion, so if you're targeting older .NET Framework versions, you'll get different values compared to when you target more modern versions of .NET (.NET Core, .NET 5, .NET 6, and anything later than that).
  • AddMacAddress adds the MAC address to the device identifier.
  • AddFileToken adds a unique token stored in a file to the device identifier. The file is created if it doesn't already exist. Fails silently if no permissions available to access the file.

From DeviceId.Windows:

  • AddWindowsDeviceId adds the Windows Device ID (also known as Machine ID or Advertising ID) to the device identifier. This value is the one displayed as "Device ID" in the Windows Device Specifications UI.
  • AddWindowsProductId adds the Windows Product ID to the device identifier. This value is the one displayed as "Product ID" in the Windows Device Specifications UI.
  • AddRegistryValue adds a specified registry value to the device identifier.
  • AddMachineGuid adds the machine GUID from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography to the device identifier.

From DeviceId.Windows.Wmi / DeviceId.Windows.WmiLight / DeviceId.Windows.Mmi:

  • AddMacAddressFromWmi / AddMacAddressFromMmi adds the MAC address to the device identifier. These use the improved query functionality from WMI/MMI to provide additional functionality over the basic AddMacAddress method (such as being able to exclude non-physical device).
  • AddProcessorId adds the processor ID to the device identifier.
  • AddSystemDriveSerialNumber adds the system drive's serial number to the device identifier.
  • AddMotherboardSerialNumber adds the motherboard serial number to the device identifier.
  • AddSystemUuid adds the system UUID to the device identifier.

From DeviceId.Linux:

  • AddSystemDriveSerialNumber adds the system drive's serial number to the device identifier.
  • AddMotherboardSerialNumber adds the motherboard serial number to the device identifier.
  • AddMachineId adds the machine ID (from /var/lib/dbus/machine-id or /etc/machine-id) to the device identifier.
  • AddProductUuid adds the product UUID (from /sys/class/dmi/id/product_uuid) to the device identifier.
  • AddCpuInfo adds CPU info (from /proc/cpuinfo) to the device identifier.
  • AddDockerContainerId adds the Docker container identifier (from /proc/1/cgroup) to the device identifier.

From DeviceId.Mac:

  • AddSystemDriveSerialNumber adds the system drive's serial number to the device identifier.
  • AddPlatformSerialNumber adds IOPlatformSerialNumber to the device identifier.

From DeviceId.SqlServer:

  • AddServerName adds the server name to the device identifier.
  • AddDatabaseName adds the server name to the device identifier.
  • AddDatabaseId adds the database ID to the device identifier.
  • AddServerProperty adds a specified server property to the device identifier.
  • AddServerProperty adds a specified extended property to the device identifier.

Dealing with MAC Address randomization and virtual network adapters

Non physical network adapters like VPN connections tend not to have fixed MAC addresses. For wireless (802.11 based) adapters hardware (MAC) address randomization is frequently applied to avoid tracking with many modern operating systems support this out of the box. This makes wireless network adapters bad candidates for device identification.

Using the cross-platform AddMacAddress, you can exclude wireless network adapters like so:

string deviceId = new DeviceIdBuilder()
    .AddMacAddress(excludeWireless: true)
    .ToString();

If you're on Windows, you can also exclude non-physical adapters using the DeviceId.Windows.Wmi or DeviceId.Windows.Mmi packages like so:

string deviceId = new DeviceIdBuilder()
    .AddMacAddress(excludeWireless: true)
    .OnWindows(windows => windows
        .AddMacAddressFromWmi(excludeWireless: true, excludeNonPhysical: true)
    .ToString()

Controlling how the device identifier is formatted

Use the UseFormatter method to set the formatter:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .UseFormatter(new HashDeviceIdFormatter(() => SHA256.Create(), new Base32ByteArrayEncoder()))
    .ToString();

The "default" formatters are available in DeviceIdFormatters for quick reference. The default formatter changed between version 5 and version 6 of the library. If you're using version 6 but want to revert to the version 5 formatter, you can do so:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .UseFormatter(DeviceIdFormatters.DefaultV5)
    .ToString();

For more advanced usage scenarios, you can use one of the out-of-the-box implementations of IDeviceIdFormatter in the DeviceId.Formatters namespace, or you can create your own.

  • StringDeviceIdFormatter - Formats the device ID as a string containing each component ID, using any desired component encoding.
  • HashDeviceIdFormatter - Formats the device ID as a hash string, using any desired hash algorithm and byte array encoding.
  • XmlDeviceIdFormatter - Formats the device ID as an XML document, using any desired component encoding.

There are a number of encoders that can be used customize the formatter. These implement IDeviceIdComponentEncoder and IByteArrayEncoder and are found in the DeviceId.Encoders namespace.

Supporting/validating multiple device ID formats with backwards compatibility

Let's say you shipped an app, and were using DeviceId to perform license checks. You may have done something like:

var currentDeviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddUserName()
    .AddMacAddress()
    .ToString();

var savedDeviceIdFromLicenseFile = ReadDeviceIdFromLicenseFile();

var isLicenseValid = currentDeviceId == savedDeviceIdFromLicenseFile;

Say you now want to release a new version of your app, and want to change how new device identifiers are generated (maybe just use MAC address and a file token), but you don't want to invalidate every single license file that currently exists. In other words, you want backwards compatible device ID validation.

In the latest version of DeviceId, you can use the DeviceIdManager to do so:

var deviceIdManager = new DeviceIdManager()
    .AddBuilder(1, builder => builder
        .AddMachineName()
        .AddUserName()
        .AddMacAddress())
    .AddBuilder(2, builder => builder
        .AddMacAddress()
        .AddFileToken(TokenFilePath));

var savedDeviceIdFromLicenseFile = ReadDeviceIdFromLicenseFile();

var isLicenseValid = deviceIdManager.Validate(savedDeviceIdFromLicenseFile);

The device ID manager will work out which builder to use, and generate the current device ID in the correct format so that it can be sensibly compared to the device ID being validated.

Note that this functionality all works well but I'm not entirely happy with the naming or the API. I've currently built it so that there are no breaking changes for v6. In the future (v7 for example) I may rename some classes and break the API. In any case though I will keep the functionality, so it's safe to use this stuff.

Migration Guide 5.x -> 6.x

There were a few breaking changes going from v5 to v6.

  • As mentioned above in the "What packages are needed" section, DeviceId was split into multiple packages, so you may need to add a reference to the packages for your platform (such as DeviceId.Windows, DeviceId.Windows.Wmi, DeviceId.Linux, etc.).

  • As mentioned above in the "Controlling how the device identifier is formatted" section, the default formatter changed between version 5 and version 6. If you're using version 6 but want to revert to the version 5 formatter, you can do so via .UseFormatter(DeviceIdFormatters.DefaultV5)

  • Some methods have been renamed or restricted to certain platforms. You can inspect the version 5.x methods and choose the corresponding new OS-specific methods. Note that these still may not be backwards compatible with a v5 device identifier due to the changes in the component names. Remember, if something is missing in v6 that you had in v5, you can always re-add it yourself via a custom component. Here are some examples of changes:

// V5:
builder.AddOSInstallationID();

// V6:
builder.OnWindows(x => x.AddMachineGuid())
       .OnLinux(x => x.AddMachineId())
       .OnMac(x => x.AddPlatformSerialNumber());
// V5:
builder.AddMotherboardSerialNumber();

// V6:
builder.OnWindows(x => x.AddMotherboardSerialNumber())
       .OnLinux(x => x.AddMotherboardSerialNumber());
       // not available on Mac
// V5:
builder.AddSystemUUID();

// V6:
builder.OnWindows(x => x.AddSystemUuid())
       .OnLinux(x => x.AddProductUuid());
       // not available on Mac
// V5:
builder.AddSystemUUID();

// V6:
builder.OnWindows(x => x.AddProcessorId())
       .OnLinux(x => x.AddCpuInfo());
       // not available on Mac

Strong naming

From version 5 onwards, the assemblies in this package are strong named for the convenience of those users who require strong naming. Please note, however, that the key files are checked in to this repository. This means that anyone can compile their own version and strong name it with the original keys. This is a common practice with open source projects, but it does mean that you shouldn't use the strong name as a guarantee of security or identity.

License and copyright

Copyright Matthew King 2015-2021. Distributed under the MIT License. Refer to license.txt for more information.

Support DeviceId

Community support is greatly appreciated. You can help in the following ways:

deviceid's People

Contributors

adamcaviness avatar alexschuetz avatar cakkermans avatar james231 avatar klyse avatar koncord avatar matihuf avatar matthewking avatar phrohdoh avatar progdogusmc avatar shshzi avatar techtim avatar thoron avatar twistie avatar zaczero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

deviceid's Issues

Error: Could not load file or assembly Microsoft.Management.Infrastructure

DeviceId: 5.3.0
Running the app on windows 10 I have the following error:

 Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at DeviceId.Internal.Wmi.GetValues(String className, String propertyName)
   at DeviceId.Components.WmiDeviceIdComponent.GetValue()
   at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__3_1(IDeviceIdComponent x)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IEnumerable`1 components)
   at DeviceId.DeviceIdBuilder.ToString()

My code looks like this:

var systemId = new DeviceIdBuilder()
                .AddProcessorId()
                .AddMotherboardSerialNumber()
                .AddSystemUUID()
                .AddOSInstallationID()
                .UseFormatter(new HashDeviceIdFormatter(() => MD5.Create(), new Base64UrlByteArrayEncoder()))
                .ToString();

Is it a bug or am I doing something wrong? Appreciate any help.

DeviceID returns different IDs?

Hello,

there is a problem with the library - maybe you can find out why the DeviceID returns different ID strings.

  1. I used the library direct with NuGet package
  2. I used the same function from my own library in COM Inteorp with Excel VBA

The strange thing is i get two different IDs from the library - but how i said its the same function.
Under this is my "Testcode" with the two different outputs.

In the end you can see i tried first the DeviceID library and after that i used directly the System.Management.
With the System.Management i get two times the same ID.

        string one = new DeviceIdBuilder().AddMachineName().ToString();
        string two = new DeviceIdBuilder().OnWindows(windows => windows.AddProcessorId()).ToString();
        string three = new DeviceIdBuilder().OnWindows(windows => windows.AddMotherboardSerialNumber()).ToString();
        string four = new DeviceIdBuilder().OnWindows(windows => windows.AddSystemSerialDriveNumber()).ToString();

        string uniqueID = new DeviceIdBuilder()
            .AddMachineName()
            .OnWindows(windows => windows
                .AddProcessorId()
                .AddMotherboardSerialNumber()
                .AddSystemSerialDriveNumber())
            //.OnLinux(linux => linux
            //    .AddMotherboardSerialNumber()
            //    .AddSystemDriveSerialNumber())
            //.OnMac(mac => mac
            //    .AddSystemDriveSerialNumber()
            //    .AddPlatformSerialNumber())
            .ToString();

        var mbs = new ManagementObjectSearcher("Select ProcessorId From Win32_processor");
        ManagementObjectCollection mbsList = mbs.Get();
        string id = "";
        foreach (ManagementObject mo in mbsList)
        {
            id = mo["ProcessorId"].ToString();
            break;
        }`

DeviceIDBuilder_COMInterop_Excel
DeviceIDBuilder_VS_Winform
DeviceID_vs_SystemManagement

Using package DeviceId.Wmi - MotherboardSerialNumber gives WPF scroll issues

For a full stack WPF application with multiple projects the DeviceId.Wmi library for some reason gives touch scroll issues when used.

Adding the library as Nuget package to my Infrastructure layer project would make my WPF UI layer project give touch scroll issues. The touch still works but the scrollviewer in particular could not easily be scrolled anymore (PanningMode is set to Both).

I have created a simple project where the issue is active: TestTouchScroll-issue.zip. If you comment the lines in the MainWindow.xaml.cs - line 15 to 18 the problem is fixed. So it has to do something with the .AddMotherboardSerialNumber() or .AddMachineGuid() method that is called. I also found out that removing the MotherboardSerialNumber method fixes the issue. (the MachineGuid method doesn't use the Wmi library, i suspect the problem to lie in the Wmi library).

Hopefully this information is useful enough and feel free to ask for more information if required! Thank you in advance! Great library never the less!

Cheers, Pepijn

Incompatible when used with .NET 5 in SingleFile option

I have a sample WPF project running on .NET 5. Everything works fine for both debug and release environments. However, if I publish the project with target runtime as win-x64 or win-x86 with "Produce Single File" option, the following error occurs.

image

image

This error is logged with Serilog

Downgrade the System.Management dependency to version 6 for .net standard 2.0

Hi all!

Can we consider downgrading the System.Management dependency to version 6 for .net standard 2.0 target of the DeviceId.Windows.Wmi package? It is currently dependent on version 7 which is incompatible with .net core 3.1 and .net 5 which are covered by the .net standard 2.0 umbrella.

Screenshot 2023-09-18 at 14 21 45

Thanks a lot for all this incredible work, by the way!

Device ID on docker container

Hi,
I have a question about docker container in particular running on azure.
I am using DeviceId library to have a unque ID for generating license for customer that want to use our company software.
I experienced that on any container creation (and it is also correct) the DeviceID changes and therefore license become invalid.
When running docker hosted in azure could be useful to get the Azure tenantId of the current running subscription.
In general I would like to have a unique ID when running docker even after having built a new container.

Any suggestion?
Thanks in advance

Version compatible

Hi,
I am using version 5.2 for generating DeviceID as follows:
string deviceId = new DeviceIdBuilder()
.AddMachineName()
.AddProcessorId()
.AddMotherboardSerialNumber()
.ToString();

I noted that on version 6.2 the "same" instructions generate a different result:
string deviceId = new DeviceIdBuilder()
.AddMachineName()
.OnWindows(windows => windows.AddProcessorId().AddMotherboardSerialNumber())
.ToString();

Is possible to generated a device ID which is back-compatible with version 5.2?

Thanks in advance
Luigi

lsblk issue on CentOs 7

Hello,
I have used this in one of our apps which has been deployed on a CentOs 7 OS. This is failing because the command "lsblk -f -J" doesn't return a valid result on CentOS

`[root@eu~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
[root@eu-p-mongo-2 ~]# lsblk -f -J
lsblk: invalid option -- 'J'

Usage:
lsblk [options] [ ...]

Options:
-a, --all print all devices
-b, --bytes print SIZE in bytes rather than in human readable format
-d, --nodeps don't print slaves or holders
-D, --discard print discard capabilities
-e, --exclude exclude devices by major number (default: RAM disks)
-I, --include show only devices with specified major numbers
-f, --fs output info about filesystems
-h, --help usage information (this)
-i, --ascii use ascii characters only
-m, --perms output info about permissions
-l, --list use list format output
-n, --noheadings don't print headings
-o, --output output columns
-p, --paths print complate device path
-P, --pairs use key="value" output format
-r, --raw use raw output format
-s, --inverse inverse dependencies
-t, --topology output info about topology
-S, --scsi output info about SCSI devices

-h, --help display this help and exit
-V, --version output version information and exit

Available columns (for --output):
NAME device name
KNAME internal kernel device name
MAJ:MIN major:minor device number
FSTYPE filesystem type
MOUNTPOINT where the device is mounted
LABEL filesystem LABEL
UUID filesystem UUID
PARTLABEL partition LABEL
PARTUUID partition UUID
RA read-ahead of the device
RO read-only device
RM removable device
MODEL device identifier
SERIAL disk serial number
SIZE size of the device
STATE state of the device
OWNER user name
GROUP group name
MODE device node permissions
ALIGNMENT alignment offset
MIN-IO minimum I/O size
OPT-IO optimal I/O size
PHY-SEC physical sector size
LOG-SEC logical sector size
ROTA rotational device
SCHED I/O scheduler name
RQ-SIZE request queue size
TYPE device type
DISC-ALN discard alignment offset
DISC-GRAN discard granularity
DISC-MAX discard max bytes
DISC-ZERO discard zeroes data
WSAME write same max bytes
WWN unique storage identifier
RAND adds randomness
PKNAME internal parent kernel device name
HCTL Host:Channel:Target:Lun for SCSI
TRAN device transport type
REV device revision
VENDOR device vendor

For more details see lsblk(8).
[root@eu ~]#
`

DeviceIdBuilder hangs due to Windows AddSystemSerialDriveNumber() call when using DeviceId.Windows.Mmi

I updated my nuget package reference(s)to 6.0.0 today and used your new syntax for various platforms. I experienced consistent hanging when adding in the drive serial number AddSystemSerialDriveNumber() for Windows:

var deviceId = new DeviceIdBuilder()
		.AddMachineName()
		.OnWindows(windows => windows
			.AddProcessorId()
			.AddMotherboardSerialNumber()
			.AddSystemSerialDriveNumber())
		.ToString();

Package references:

<PackageReference Include="DeviceId.Mac" Version="6.0.0" />
<PackageReference Include="DeviceId.Windows" Version="6.0.0" />
<PackageReference Include="DeviceId.Windows.Mmi" Version="6.0.0" />

The hang goes away when I use the WMI package instead <PackageReference Include="DeviceId.Windows.Wmi" Version="6.0.0" />. Alternatively, I can keep the MMI package and remove the call to AddSystemSerialDriveNumber().

Might I also ask why the language changed for the the method AddSystemSerialDriveNumber()? It used to be AddSystemDriveSerialNumber() like the other platforms. Lastly, thank you for the excellent work that went into this library.

Could not load file or assembly 'System.Management

i run this code on my asp.net core website and its working even published to iis
string mbInfo = new DeviceIdBuilder() .OnWindows(x => { x.AddMotherboardSerialNumber(); }) .ToString() .Substring(0,7);
but on windows server in iis gives me shuch a log

  System.IO.FileNotFoundException: Could not load file or assembly 'System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

Add support for .NET 5 (and later)

DeviceId targets .NETStandard 2.0, so in principle it should work on net5.0. Unfortunately, the project uses the obsolete platform abstraction package, which is not available for net5.0 (except for an old preview version). For that reason, it would be great to have a net5.0 target. Once #25 is merged, the net5.0 version would be identical to the netStandard version, except for the deprecated dependency.

See https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/platformabstractions-package-removed for details.

.NET Standard with Nuget package

Could it be that the .NET standard version is missing some code? I just added deviceId 4.0 to y .NET standard 2.0 project, and it seems the dll does not contain the DeviceIdBuilderExtensions, so calling any .AddXYZ() methods on the DeviceIdBuilder is not possible.

Convert String to Component

After creating a deviceId, how do you convert it back if you know the conponents of builder?
I am trying to create a client and server communication.

Use inheritance for specific DeviceIdBuilders

Hi,

I've noticed, that using general device ID features like the OS version can't be used device specific. This means, it is possible to call AddOsVersion not dependent on the system you are running on:

This works:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .AddOsVersion()
    .OnWindows(windows => windows
        .AddProcessorId())
    .OnLinux(linux => linux
        .AddCpuInfo())
    .ToString();

This works not:

string deviceId = new DeviceIdBuilder()
    .AddMachineName()
    .OnWindows(windows => windows
        .AddProcessorId())
    .OnLinux(linux => linux
        .AddOsVersion()
        .AddCpuInfo())
    .ToString();

The reason seems to be some type specific handling here. From my point of view, this could be solved by changing the way to create the specific builders to inheritance.

If LinuxDeviceIdBuilder inherits from DeviceIdBuilder, overriding the corresponding methods, this would solve the problem. As an alternative the base builder property could be made public. Is there a reason why this is not done like this? If not, I could create a PR with the proposed changes. Let me know what you think about it.

Trigger Nuget build

The last version is 4 months old, please update Nuget with the latest commits for OSX

[feature] add a static method for simple and quick use

adding this static method:

DeviceId.FingerPrint(systemUUID: true, processorId: true, motherboardSN: true, hashAlgo: DeviceIdHashAlgorithms.MD5, separatorChar: ":", separatorEveryChars: 4)

to output:

5C7D:0C90:CF9E:0CE5:6095:6179:E8E8:2E7D

HashAlgorithms.None (plain)
HashAlgorithms.MD5
HashAlgorithms.SHA1
HashAlgorithms.SHA256

would be more practical in usage.

Mistake in migration guide?

The migration guide in the readme states that for AddOSInstallationID (on mac) the equivalent in v6+ should be AddSystemDriveSerialNumber but - looking at the v5 & v6 implementations I think the README should state the equivalent is actually AddPlatformSerialNumber.

AddOSInstallationID v5:

return builder.AddComponent(new CommandComponent(
name: "OSInstallationID",
command: "ioreg -l | grep IOPlatformSerialNumber | sed 's/.*= //' | sed 's/\"//g'",
commandExecutor: CommandExecutor.Bash));

AddPlatformSerialNumber v6:

return builder.AddComponent("IOPlatformSerialNumber", new CommandComponent("ioreg -l | grep IOPlatformSerialNumber | sed 's/.*= //' | sed 's/\"//g'", CommandExecutor.Bash));

The commands executed are identical between these two (and not in AddSystemDriveSerialNumber)

DeviceId changed every time after reboot

I'm using new DeviceIdBuilder().AddMacAddress().AddMotherboardSerialNumber().ToString() to identify a unique computer.
But it always changing after a reboot. Am I using it right ?

Not Generating DeviceId on CentOs 7

Below you can find Error details.

lsblk: invalid option -- 'J'

Usage:
lsblk [options] [ ...]

Options:
-a, --all print all devices
-b, --bytes print SIZE in bytes rather than in human readable format
-d, --nodeps don't print slaves or holders
-D, --discard print discard capabilities
-e, --exclude exclude devices by major number (default: RAM disks)
-I, --include show only devices with specified major numbers
-f, --fs output info about filesystems
-h, --help usage information (this)
-i, --ascii use ascii characters only
-m, --perms output info about permissions
-l, --list use list format output
-n, --noheadings don't print headings
-o, --output output columns
-p, --paths print complate device path
-P, --pairs use key="value" output format
-r, --raw use raw output format
-s, --inverse inverse dependencies
-t, --topology output info about topology
-S, --scsi output info about SCSI devices

-h, --help display this help and exit
-V, --version output version information and exit

Available columns (for --output):
NAME device name
KNAME internal kernel device name
MAJ:MIN major:minor device number
FSTYPE filesystem type
MOUNTPOINT where the device is mounted
LABEL filesystem LABEL
UUID filesystem UUID
PARTLABEL partition LABEL
PARTUUID partition UUID
RA read-ahead of the device
RO read-only device
RM removable device
MODEL device identifier
SERIAL disk serial number
SIZE size of the device
STATE state of the device
OWNER user name
GROUP group name
MODE device node permissions
ALIGNMENT alignment offset
MIN-IO minimum I/O size
OPT-IO optimal I/O size
PHY-SEC physical sector size
LOG-SEC logical sector size
ROTA rotational device
SCHED I/O scheduler name
RQ-SIZE request queue size
TYPE device type
DISC-ALN discard alignment offset
DISC-GRAN discard granularity
DISC-MAX discard max bytes
DISC-ZERO discard zeroes data
WSAME write same max bytes
WWN unique storage identifier
RAND adds randomness
PKNAME internal parent kernel device name
HCTL Host:Channel:Target:Lun for SCSI
TRAN device transport type
REV device revision
VENDOR device vendor

For more details see lsblk(8).
Unhandled exception. System.Text.Json.JsonException: The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
---> System.Text.Json.JsonReaderException: The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. LineNumber: 0 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan1 bytes) at System.Text.Json.Utf8JsonReader.Read() at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
--- End of inner exception stack trace ---
at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable1 actualByteCount) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 json, JsonTypeInfo jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at DeviceId.Linux.Components.LinuxRootDriveSerialNumberDeviceIdComponent.GetValue()
at DeviceId.Formatters.HashDeviceIdFormatter.<>c.b__3_1(KeyValuePair2 x) at System.Linq.Enumerable.SelectIPartitionIterator2.PreallocatingToArray(Int32 count)
at System.Linq.Enumerable.SelectIPartitionIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary`2 components)
at DeviceId.DeviceIdBuilder.ToString()
at uOPCSuite.DeviceId.Program.Main(String[] args)

Release documentation

Hi,
I tried to upgrade from 5.2.0 to 6.0.0.

Unfortunately the API changed and I don't know if this would affect my program, by returning different DeviceIds for the same machine/configuration or if I need to do some migration.

For example the AddOSInstallationID-method, that I use is gone.

It would be great if you document your releases and possibly breaking changes.

After Update nothing works.

After 6.0.0 update you change much, readme is outdated.
.AddProcessorId.. does not exist anymore.

What you change?

Permissions levels?

I am using v5.3 of the library (a bit old, but I haven't fully tested the new version).

I have the following for generating an unique id for each user:

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
    try
    {
        return new DeviceIdBuilder()
            .AddProcessorId()
            .AddComponent(new CDriveSerialNumber())
            .ToString();
    }
    catch
    {
        return new DeviceIdBuilder()
            .AddProcessorId()
            .AddSystemDriveSerialNumber()
            .ToString();
    }
}

public class CDriveSerialNumber : IDeviceIdComponent
{
    public string Name { get; } = "CDriveSerialNumber";

    public string GetValue()
    {
        using (var mo = new ManagementObject("win32_logicaldisk.deviceid=\"C:\""))
        {
            return mo["VolumeSerialNumber"].ToString();
        }
    }
}

I have some exception telemetry set up and every once in a while, I saw the following:

System.UnauthorizedAccessException: Access is denied. (0x80070005 (E_ACCESSDENIED))
   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode, IntPtr errorInfo)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at System.Management.ManagementObject.Initialize(Boolean getObject)
   at System.Management.ManagementBaseObject.get_Properties()
   at System.Management.ManagementBaseObject.GetPropertyValue(String propertyName)
   at System.Management.ManagementBaseObject.get_Item(String propertyName)
   at Base.CDriveSerialNumber.GetValue()

So I added the try-catch with AddSystemDriveSerialNumber instead and definitely see this issue less often, but I still see a bit of:

Microsoft.Management.Infrastructure.CimException: Access is denied. 
  ?, in bool CimSyncEnumeratorBase<T>.MoveNext()
  ?, in string Wmi.GetSystemDriveSerialNumber()
  ?, in string SystemDriveSerialNumberDeviceIdComponent.GetValue()

Basically, what I'm asking is the following: what are the most stable id properties (least likely to change - like motherboard serial number as opposed to MAC address or OS Version) that also require the least permissions to access (for instance, I don't think I've ever seen an issue with my usage of AddProcessorId)?

Additionally, do you know of any resource that could rank all the component builders in DeviceId according to the permissions level required? I've been trying to find some resources online, but can't find anything

AddCpuInfo always return new id

Hi,

Method AddCpuInfo for linux is reading /proc/cpuinfo and using FileContentsDeviceIdComponent for getting cpu id.

First command run
cpuinfo

Second command run
cpuinfo2

Please take a look at cpu MHz field, is changing depending on cpu usage.

JsonException when generating Id on Alpine Linux

Hello,
I am facing an issue generating a device id that happens only on Alpine Linux. The specific context is a docker container using the official dotnet/sdk:7.0-alpine image. On Windows and on my Ubuntu container everything runs fine.

The code used to generate the machine ID is this one:

new DeviceIdBuilder()
        .AddMacAddress(true)
        .OnWindows(windows => windows
            .AddProcessorId()
            .AddMotherboardSerialNumber()
            .AddSystemDriveSerialNumber())
        .OnLinux(linux => linux
            .AddCpuInfo()
            .AddMotherboardSerialNumber()
            .AddSystemDriveSerialNumber())
        .ToString()

And the error I'm getting is this one:

System.TypeInitializationException : The type initializer for 'XXX.Common.Utilities.Security.Device' threw an exception.
---- System.Text.Json.JsonException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
-------- System.Text.Json.JsonReaderException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. LineNumber: 0 | BytePositionInLine: 0.
  Stack Trace:
     at XXX.Common.Utilities.Security.Device.get_Id() in /builds/XXX/common/Utilities/Security/Device.cs:line 17
   at XXX.Common.Test.Utilities.Security.DeviceTests.Id() in /builds/XXX/common/Test/Utilities/Security/Device.cs:line 20
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
----- Inner Stack Trace -----
   at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& state, JsonReaderException ex)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo jsonTypeInfo, Nullable`1 actualByteCount)
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo jsonTypeInfo)
   at DeviceId.Linux.Components.LinuxRootDriveSerialNumberDeviceIdComponent.GetValue()
   at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__4_1(KeyValuePair`2 x)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
   at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary`2 components)
   at DeviceId.DeviceIdBuilder.ToString()
   at XXX.Common.Utilities.Security.Device..cctor() in /builds/XXX/common/Utilities/Security/Device.cs:line 17
----- Inner Stack Trace -----
   at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
   at System.Text.Json.Utf8JsonReader.Read()
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)

I would appreciate any feedback even if it's that alpine linux is not supported. Thanks.

does not work on Windows 7 enterprise sp1

The Win7 OS only install .net 6 runtime, and my code reference DeviceId.Windows.Mmi.
When I try to get device id, it throw error message as below, and I found the relate issue of mmi PowerShell/MMI#43

Time:2022-06-01 11:50:32.6242
Software version: 1.0.0.0
Operating system information:
Message:
Microsoft.Management.Infrastructure.CimException: FAILED
at Microsoft.Management.Infrastructure.CimException.ThrowIfMiResultFailure(MiResult result, String errorMessage, InstanceHandle errorData)
at Microsoft.Management.Infrastructure.CimException.ThrowIfMiResultFailure(MiResult result, InstanceHandle errorData)
at Microsoft.Management.Infrastructure.CimSession.Create(String computerName, CimSessionOptions sessionOptions)
at DeviceId.Windows.Mmi.Components.MmiSystemDriveSerialNumberDeviceIdComponent.GetValue()
at DeviceId.Formatters.HashDeviceIdFormatter.<>c.b__3_1(KeyValuePair2 x) at System.Linq.Enumerable.SelectIPartitionIterator2.PreallocatingToArray(Int32 count)
at System.Linq.Enumerable.SelectIPartitionIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary2 components) at DeviceId.DeviceIdBuilder.ToString() at Microsoft.Practices.EnterpriseLibrary.Security.SerialKeyManager.GetDeviceId(String productName, String productVersion) at Omec.ResistanceCounter.ViewModels.Common.SerialNumberHelper.GetCurrentMachineSerialNumber(String productName, String productVersion) in C:\Projects\ResistanceCounter\Omec.ResistanceCounter\Omec.ResistanceCounter.ViewModels\Common\SerialNumberHelper.cs:line 28 at Microsoft.Management.Infrastructure.CimException.ThrowIfMiResultFailure(MiResult result, String errorMessage, InstanceHandle errorData) at Microsoft.Management.Infrastructure.CimException.ThrowIfMiResultFailure(MiResult result, InstanceHandle errorData) at Microsoft.Management.Infrastructure.CimSession.Create(String computerName, CimSessionOptions sessionOptions) at DeviceId.Windows.Mmi.Components.MmiSystemDriveSerialNumberDeviceIdComponent.GetValue() at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__3_1(KeyValuePair2 x)
at System.Linq.Enumerable.SelectIPartitionIterator2.PreallocatingToArray(Int32 count) at System.Linq.Enumerable.SelectIPartitionIterator2.ToArray()
at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary2 components)
at DeviceId.DeviceIdBuilder.ToString()
at Microsoft.Practices.EnterpriseLibrary.Security.SerialKeyManager.GetDeviceId(String productName, String productVersion)
at Omec.ResistanceCounter.ViewModels.Common.SerialNumberHelper.GetCurrentMachineSerialNumber(String productName, String productVersion) in C:\Projects\ResistanceCounter\Omec.ResistanceCounter\Omec.ResistanceCounter.ViewModels\Common\SerialNumberHelper.cs:line 28

DeviceId doesn't work in docker for Windows containers.

Hello,

we use DeviceId in docker. It works in a Linux container, but not in a Windows container.
You support AddDockerContainerId for DeviceId.Linux in the README file. Do you also support Windows containers?

I found the problem where it fails is on this line:

var systemLogicalDiskDeviceId = Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 2);

Environment.SpecialFolder.System returns "System"
Environment.GetFolderPath(Environment.SpecialFolder.System) returns an empty string so Substring(0, 2) fails.

Failure with this code:

string deviceId = new DeviceIdBuilder()
    .OnWindows(windows => windows
        .AddProcessorId()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber()
        .AddSystemUuid())
    .OnLinux(linux => linux
        .AddCpuInfo()
        .AddMotherboardSerialNumber()
        .AddSystemDriveSerialNumber()
        .AddMachineId())
    .AddFileToken(TokenFilePath)
    .AddMachineName()
    .ToString();

Stack Trace:

at System.String.ThrowSubstringArgumentOutOfRange(Int32 startIndex, Int32 length) in /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs:line 1878\r\n   
at System.String.Substring(Int32 startIndex, Int32 length) in /_/src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs:line 1852\r\n  
at DeviceId.Windows.Wmi.Components.WmiSystemDriveSerialNumberDeviceIdComponent.GetValue() in /_/src/DeviceId.Windows.Wmi/Components/WmiSystemDriveSerialNumberDeviceIdComponent.cs:line 23\r\n
at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__3_1(KeyValuePair`2 x) in /_/src/DeviceId/Formatters/HashDeviceIdFormatter.cs:line 47\r\n  
at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count) in /_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs:line 606\r\n  
at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray() in /_/src/libraries/System.Linq/src/System/Linq/Select.SpeedOpt.cs:line 620\r\n   
at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IDictionary`2 components) in /_/src/DeviceId/Formatters/HashDeviceIdFormatter.cs:line 47\r\n   
at DeviceId.DeviceIdBuilder.ToString() in /_/src/DeviceId/DeviceIdBuilder.cs:line 54\r\n  

Probably the same problem here:

var systemLogicalDiskDeviceId = Environment.GetFolderPath(Environment.SpecialFolder.System).Substring(0, 2);

Thank you in advance for your feedback.

System.PlatformNotSupportedException on Win Server 2012

Hi, I write a .net5 app that try to get the machine id. The code is simple:

public string GetId() => new DeviceIdBuilder()
                                .AddProcessorId()
                                .AddMacAddress(true, true)
                                .ToString();

It works fine on win 10, but on a win server 2012 I get this error: System.PlatformNotSupportedException: The native library 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\wminet_utils.dll' does not have all required functions. Please, update the .NET Framework.

I then install the .net framework 4.8 , but it doesn't help.

NET8.0 DeviceId.Windows.Mmi not working

Hi,
Recently i was migrating one of my projects to NET8 RC2.
Noted that DeviceId.Windows.Mmi throws an error.

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at DeviceId.Windows.Mmi.Components.MmiWqlDeviceIdComponent.GetValue()

the package which throws the error is included inside DeviceId.Windows.Mmi

by removing MMI reference, at least for windows (11) all seems to work.

The error occurs only on runtime, but compiles fine.
Inside build folder there are files like:
DeviceId.*.dll
but no explicitly the dll that throws the error althought i assume its included in DeviceId.Windows.Mmi.dll

here is my configuration:

//excluding wireless and non physical becouse they might change MAC more easily
var deviceIdBuilder = new DeviceIdBuilder()
    .AddOsVersion()
    .OnWindows(windows => windows
        .AddMachineGuid()
        .AddWindowsDeviceId()
        .AddWindowsProductId()
        //mmi stopped working in NET8.0
        //.AddMacAddressFromMmi(excludeWireless: true, excludeNonPhysical: true)
        //.AddSystemUuid()
        )
    .OnLinux(linux => linux
        .AddProductUuid()
        .AddMotherboardSerialNumber()
        )
    .OnMac(mac => mac
        .AddPlatformSerialNumber()
        );

//Processor Id creates issues on linux as it may change (if programm is executing on different Processor from before)
//[Windows] -> AddSystemUuid seems not to be unique (at least in .NET)
var MachineId = deviceIdBuilder
    .UseFormatter(new HashDeviceIdFormatter(() =>
        SHA256.Create(),
        new Base64UrlByteArrayEncoder()
     ))
    .ToString();

Thanks in advance.

Migration to v6

Hello, I recently migrated your library to version 6.
With big disappointing I can't get the same result as version 5.
This is my code:

// old code
         string deviceIdV5 = new DeviceIdBuilder()
               .AddSystemUUID()
               .AddProcessorId()
               .AddMotherboardSerialNumber()
               .AddSystemDriveSerialNumber()
               .ToString();
// new code
            string deviceIdV6 = new DeviceIdBuilder()
                .OnWindows(w => w
                    .AddSystemUuid()
                    .AddProcessorId()
                    .AddMotherboardSerialNumber()
                    .AddSystemDriveSerialNumber()
                    )
                .OnLinux(l => l
                    .AddCpuInfo()
                    .AddMachineId()
                    .AddProductUuid()
                    .AddMotherboardSerialNumber()
                    .AddSystemDriveSerialNumber()
                    )
                .ToString();

Is there a way to get the new code generate the same value as the old one?

AddOSInstallationID

Hello
Returning different values for "AddOSInstallationID" method net5 and framework 4.7.2

Validate the DeviceId is semantically correct

I am attempting to validate that a DeviceId provided via a web form is valid - but I do not have access to the machine that the deviceId would have been generated.

I am attempting to check that the device Id provided is correct in that it could have been generated on a machine - and isn't simply a jumble of characters typed into the textbox.

Aside from checking the length and looking for invalid characters (Is there a list?), is there anything I can do to check the semantic correctness of the string? Does the length vary?

Many thanks for any help and for creating this great software!

Dockersupport

If the application runs in a docker container some functions won't work:

  • AddMotherboardSerialNumber() aka/sys/class/dmi/id/board_serial won't work as the file doesn't exit
  • AddSystemUUID() aka /sys/class/dmi/id/product_uuid won't work as the file doesn't exit

Maybe: head -1 /proc/self/cgroup|cut -d/ -f3 could help out with one of them.

Device ID is not unique and changing over time

Hi, thank you for the package. I am facing an issue, I am generating the IDs in a "service worker" in Windows Service mode using the below command. I am using the base package DeviceId without any other extension packages.

 new DeviceIdBuilder()
        .AddUserName()
        .AddMachineName()
        .AddMacAddress(excludeWireless: true)
        .ToString();

It works great but in a span of few hours (on the same network & machine) the generated ID gets changed.

Isn't "Mac Address" is used as a seed to generate random string? Shouldn't that be unique always?

Processor Id vs SerialNumber

Firstly, thank you for this awesome project

Just some questions:

  1. Why do you use ProcessorId instead of SerialNumber? I guess compatibility because it looks SerialNumber "is not supported before Windows Server 2016 and Windows 10";
  2. At least for me, appears ProcessorId is something to identify a cpu model, it does not look unique enough... EDIT: I tested 2 computers with the same processor model, and the ProcessorId returned is the same... so my theory is correct. Maybe something to explain in readme.md file?
  3. Do you plan expose this Processor SerialNumber in future?

My reference for these informations is here.

DeviceIdBuilder AddSystemDriveSerialNumber() - System.Management.ManagementException: Invalid class

Hi

We're seeing an issue on some users machines (few and far in between, but regular enough to be a problem). It seems that using the AddSystemDriveSerialNumber() method for DeviceIdBuilder is causing an exception to be thrown on these machines (stack trace below). We are currently still using 5.2.0 primarily due to the WMI vs MMI issue, so I would expect to receive the same issue on the newer 6.x versions using WMI as I can't see that anything was changed in this area.

System.Management.ManagementException: Invalid class 
   at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
   at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
   at DeviceId.Components.SystemDriveSerialNumberDeviceIdComponent.GetValue()
   at DeviceId.Formatters.HashDeviceIdFormatter.<>c.<GetDeviceId>b__3_1(IDeviceIdComponent x)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count)
   at System.Linq.Enumerable.SelectIPartitionIterator`2.ToArray()
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at DeviceId.Formatters.HashDeviceIdFormatter.GetDeviceId(IEnumerable`1 components)
   at DeviceId.DeviceIdBuilder.ToString()

As this is only happening on some machines, and we don't have direct access to any of them I can't provide any code to reproduce this. I'm hoping that you may have some idea as to why this may happen and how we can work around the issue?

Thanks

Rob

How to get deviceId from Client ?

I want get deviceToken for each client requesting my site.

You want to depend on the machine, not the browser.

i tried user-agent but user-agent is depending browser and os, it is not unique.

Your library can provide deviceid of client?

Why generates different DeviceId's on different applications on same device?

I'm generating device id as: new DeviceIdBuilder().AddMachineName().AddMacAddress().AddOsVersion().ToString();

I expect it generates same device id on same device even for different apps.

This statement generates DeviceId1 on App1 on Device1, however DeviceId2 on App2 (different app) on Device1 (same device).

I'm not including any app information in this statement, so app shouldn't matter if it's same device.

The things I include are:

MachineName: same
MacAddress: same
OsVersion: same

MacAddress changes

Related: #67
version: 6.4.0

I encountered an issue with AddMacAddress and setting the excludeWireless is not helping.

After installing Windows Updates the deviceId changed so I investigated a little bit.

The resulting devideId is changing in case of:

  1. Windows Update (driver updates?)
  2. Enable/Disable Bluetooth also changes the results even with excludeWireless: true

Is there a way to improve it so it will use the Mainboard NetworkAdapter or first LanAdapter found and return the Physical Address always?

System.Management equivelants?

Previously, I've been using this to generate a unique ID (based on this SO answer):

public static string GetUniquePCIdentifier()
{
    string cpuInfo = string.Empty;
    ManagementClass mc = new ManagementClass("win32_processor");
    ManagementObjectCollection moc = mc.GetInstances();

    foreach (ManagementObject mo in moc)
    {
        cpuInfo = mo.Properties["processorID"].Value.ToString();
        break;
    }

    string drive = "C";
    ManagementObject dsk = new ManagementObject(
        @"win32_logicaldisk.deviceid=""" + drive + @":""");
    dsk.Get();
    string volumeSerial = dsk["VolumeSerialNumber"].ToString();

    return cpuInfo + volumeSerial;
}

Running that on my computer gives me the ID BFEBFBFF000306C34408F4F4.

I figured the equivalent in the DeviceId library would be something like:

public static string GetUniquePCIdentifier()
{
    return new DeviceIdBuilder().AddProcessorId().AddSystemDriveSerialNumber().ToString();
}

But that gives me the ID nS9mx7meCmiAvsfZpyTLK_aQtGkgPljmld7nl4po35A (which isn't anywhere close to what I had above). Does the DeviceId library use one of the hashing formatters by default?

If possible, I'd like to migrate to this library and still keep generating the same IDs as I was before. Am I using the library correctly or is this just not possible?

Wrong ProcessorId and MotherboardSerialNumber

I'm getting "To be filled by O.E.M..BFEBFBFF000306A9" by executing:

var t = new DeviceIdBuilder().AddProcessorId().AddMotherboardSerialNumber().UseFormatter(new StringDeviceIdFormatter(new PlainTextDeviceIdComponentEncoder())).ToString();

I've tested the same code in other computer with the same result.

Here is my System Information, if its helps.

imagen

Visual Studio 2017 15.8.5
.NET Framework 4.6.1

.AddProcessorId() disappeared in version 6

Hello,
I have some apps using your lib.
None works after upgrading to version 6 because .AddProcessorId() simply is no more present.

Can you fix it or tell me how to achieve the equivalent result?

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.