0
\$\begingroup\$

I'm trying to get an unique computer (Windows) id in Unity. I can get it in .net Framework using this code, that I found somewhere:

class Security { /// <summary> /// Generates a 16 byte Unique Identification code of a computer /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9 /// </summary> private static string fingerPrint = string.Empty; public static string Value() { if (string.IsNullOrEmpty(fingerPrint)) { fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() + //"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() + "\nMAC >> "// + macId() ); } return fingerPrint; } private static string GetHash(string s) { MD5 sec = new MD5CryptoServiceProvider(); ASCIIEncoding enc = new ASCIIEncoding(); byte[] bt = enc.GetBytes(s); return GetHexString(sec.ComputeHash(bt)); } private static string GetHexString(byte[] bt) { string s = string.Empty; for (int i = 0; i < bt.Length; i++) { byte b = bt[i]; int n, n1, n2; n = (int)b; n1 = n & 15; n2 = (n >> 4) & 15; if (n2 > 9) s += ((char)(n2 - 10 + (int)'A')).ToString(); else s += n2.ToString(); if (n1 > 9) s += ((char)(n1 - 10 + (int)'A')).ToString(); else s += n1.ToString(); if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-"; } return s; } #region Original Device ID Getting Code //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { if (mo[wmiMustBeTrue].ToString() == "True") { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch (NullReferenceException e) { } } } } return result; } //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch (NullReferenceException e) { } } } return result; } private static string cpuId() { //Uses first CPU identifier available in order of preference //Don't get all identifiers, as it is very time consuming string retVal = identifier("Win32_Processor", "UniqueId"); if (retVal == "") //If no UniqueID, use ProcessorID { retVal = identifier("Win32_Processor", "ProcessorId"); if (retVal == "") //If no ProcessorId, use Name { retVal = identifier("Win32_Processor", "Name"); if (retVal == "") //If no Name, use Manufacturer { retVal = identifier("Win32_Processor", "Manufacturer"); } //Add clock speed for extra security retVal += identifier("Win32_Processor", "MaxClockSpeed"); } } return retVal; } //BIOS Identifier private static string biosId() { return identifier("Win32_BIOS", "Manufacturer") + identifier("Win32_BIOS", "SMBIOSBIOSVersion") + identifier("Win32_BIOS", "IdentificationCode") + identifier("Win32_BIOS", "SerialNumber") + identifier("Win32_BIOS", "ReleaseDate") + identifier("Win32_BIOS", "Version"); } //Main physical hard drive ID private static string diskId() { return identifier("Win32_DiskDrive", "Model") + identifier("Win32_DiskDrive", "Manufacturer") + identifier("Win32_DiskDrive", "Signature") + identifier("Win32_DiskDrive", "TotalHeads"); } //Motherboard ID private static string baseId() { return identifier("Win32_BaseBoard", "Model") + identifier("Win32_BaseBoard", "Manufacturer") + identifier("Win32_BaseBoard", "Name") + identifier("Win32_BaseBoard", "SerialNumber"); } //Primary video controller ID private static string videoId() { return identifier("Win32_VideoController", "DriverVersion") + identifier("Win32_VideoController", "Name"); } //First enabled network card ID private static string macId() { return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled"); } #endregion } 

I know that I can't use System.Management in Unity, but I found the link with deviceUniqueIdentifier that returns "unique" computer id. As described there -

returns a hash from the concatenation of strings taken from Computer System Hardware Classes

So I understood that I can get access to wmiProperties, but I don't understand how. I know that there are already some "useful" properties in SystemInfo class, but I want to access them by myself. How can I get access to these instances from Unity, like I did in .net Framework?

As @DMGregory said, I should create class library respecting this manual. I have created a class library under .NET Standart 2.1, added reference to System.Management in this project and built it. Then moved out .dll file to Assets folder in my Unity project and there was no errors, until I ran my app. I got the error:

NotImplementedException: The method or operation is not implemented. System.Management.ManagementClass..ctor (System.String path) (at <3f5769dab130437396b36bc35518b77d>:0) (wrapper remoting-invoke-with-check) System.Management.ManagementClass..ctor(string) SecurityInsideLibrary.SecurityInside.identifier (System.String wmiClass, System.String wmiProperty) (at <ffa76661f32b42f8b5668f4fbd34bc67>:0) SecurityInsideLibrary.SecurityInside.cpuId () (at <ffa76661f32b42f8b5668f4fbd34bc67>:0) SecurityInsideLibrary.SecurityInside.Value () (at <ffa76661f32b42f8b5668f4fbd34bc67>:0) SecurityHelper.GetValue () (at Assets/SecurityHelper.cs:10) MainMenuScript.Awake () (at Assets/Scenes_Legacy/UI/MainMenuScript.cs:48) 

The class library code (It is almost the same as I pasted before):

using System; using System.Text; using System.Security.Cryptography; namespace SecurityInsideLibrary { public class SecurityInside { /// <summary> /// Generates a 16 byte Unique Identification code of a computer /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9 /// </summary> private static string fingerPrint = string.Empty; public static string Value() { if (string.IsNullOrEmpty(fingerPrint)) { fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId() + //"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() + "\nMAC >> "// + macId() ); } return fingerPrint; } private static string GetHash(string s) { MD5 sec = new MD5CryptoServiceProvider(); ASCIIEncoding enc = new ASCIIEncoding(); byte[] bt = enc.GetBytes(s); return GetHexString(sec.ComputeHash(bt)); } private static string GetHexString(byte[] bt) { string s = string.Empty; for (int i = 0; i < bt.Length; i++) { byte b = bt[i]; int n, n1, n2; n = (int)b; n1 = n & 15; n2 = (n >> 4) & 15; if (n2 > 9) s += ((char)(n2 - 10 + (int)'A')).ToString(); else s += n2.ToString(); if (n1 > 9) s += ((char)(n1 - 10 + (int)'A')).ToString(); else s += n1.ToString(); if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-"; } return s; } #region Original Device ID Getting Code //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { if (mo[wmiMustBeTrue].ToString() == "True") { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch (NullReferenceException e) { } } } } return result; } //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty) { string result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch (NullReferenceException e) { } } } return result; } private static string cpuId() { //Uses first CPU identifier available in order of preference //Don't get all identifiers, as it is very time consuming string retVal = identifier("Win32_Processor", "UniqueId"); if (retVal == "") //If no UniqueID, use ProcessorID { retVal = identifier("Win32_Processor", "ProcessorId"); if (retVal == "") //If no ProcessorId, use Name { retVal = identifier("Win32_Processor", "Name"); if (retVal == "") //If no Name, use Manufacturer { retVal = identifier("Win32_Processor", "Manufacturer"); } //Add clock speed for extra security retVal += identifier("Win32_Processor", "MaxClockSpeed"); } } return retVal; } //BIOS Identifier private static string biosId() { return identifier("Win32_BIOS", "Manufacturer") + identifier("Win32_BIOS", "SMBIOSBIOSVersion") + identifier("Win32_BIOS", "IdentificationCode") + identifier("Win32_BIOS", "SerialNumber") + identifier("Win32_BIOS", "ReleaseDate") + identifier("Win32_BIOS", "Version"); } //Main physical hard drive ID private static string diskId() { return identifier("Win32_DiskDrive", "Model") + identifier("Win32_DiskDrive", "Manufacturer") + identifier("Win32_DiskDrive", "Signature") + identifier("Win32_DiskDrive", "TotalHeads"); } //Motherboard ID private static string baseId() { return identifier("Win32_BaseBoard", "Model") + identifier("Win32_BaseBoard", "Manufacturer") + identifier("Win32_BaseBoard", "Name") + identifier("Win32_BaseBoard", "SerialNumber"); } //Primary video controller ID private static string videoId() { return identifier("Win32_VideoController", "DriverVersion") + identifier("Win32_VideoController", "Name"); } //First enabled network card ID private static string macId() { return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled"); } #endregion } } 

Solution explorer:
enter image description here

Possible Solution: I'm tired of waiting for someone who can help me, so I just changed my code like:

public static string GetDeviceUniqueIdentifier() { string ret = string.Empty; string concatStr = string.Empty; try { ManagementObjectSearcher searcherBb = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard"); foreach (var obj in searcherBb.Get()) { concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty; } ManagementObjectSearcher searcherBios = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS"); foreach (var obj in searcherBios.Get()) { concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty; } ManagementObjectSearcher searcherOs = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem"); foreach (var obj in searcherOs.Get()) { concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty; } var sha1 = SHA1.Create(); ret = string.Join("", sha1.ComputeHash(Encoding.UTF8.GetBytes(concatStr)).Select(b => b.ToString("x2"))); } catch (Exception e) { Console.WriteLine(e.ToString()); } return ret; } 

(I took the code here). And the code returns the same string as SystemInfo.deviceUniqueIdentifier in Unity

\$\endgroup\$
5
  • \$\begingroup\$ In what way does deviceUniqueIdentifier differ from what you need, if your goal is just to have a unique identifier for the computer? \$\endgroup\$ Commented May 19, 2022 at 13:48
  • \$\begingroup\$ @DMGregory then I will have to change the algorithm (that I pasted) in another app, that is already in using by users. And the unique Id from that app has to be the same as in Unity app \$\endgroup\$ Commented May 19, 2022 at 13:51
  • \$\begingroup\$ That should be part of your question then. Have you considered exporting your existing code as a DLL managed or native plugin, and invoking that plugin within your Unity code? \$\endgroup\$ Commented May 19, 2022 at 13:53
  • \$\begingroup\$ Could you please give me a couple of links to read about this or provide an example of how this can be done? I will be terribly grateful. \$\endgroup\$ Commented May 19, 2022 at 14:04
  • \$\begingroup\$ Start with the documentation for an overview, then type "unity managed plugin" into your favourite search engine to find relevant tutorials and Q&A. \$\endgroup\$ Commented May 19, 2022 at 14:12

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.