I have winform application working on USB, I distribute the application on USB for the clients, I'm checking the the USB serial number if the application moved to another USB the application shows a message to the user that he cant run this app because he is not registered, I have a method getting the USB serial number by USB letter, but the problem is windows changing the USB letter dynamically, so its hard to get the USB letter and I cannot make the letter fixed so I can't read it.
I'm looking for a way to get the serial number for the USB by the USB Name is That possible ?? and if not what is the best way to manage my problem ??
Here is the Class I use to get the USB serial number :
class USBSerialNumber
{
string _serialNumber;
string _driveLetter;
public string getSerialNumberFromDriveLetter(string driveLetter)
{
this._driveLetter = driveLetter.ToUpper();
if (!this._driveLetter.Contains(":"))
{
this._driveLetter += ":";
}
matchDriveLetterWithSerial();
return this._serialNumber;
}
private void matchDriveLetterWithSerial()
{
string[] diskArray;
string driveNumber;
string driveLetter;
ManagementObjectSearcher searcher1 = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDiskToPartition");
foreach (ManagementObject dm in searcher1.Get())
{
diskArray = null;
driveLetter = getValueInQuotes(dm["Dependent"].ToString());
diskArray = getValueInQuotes(dm["Antecedent"].ToString()).Split(',');
driveNumber = diskArray[0].Remove(0, 6).Trim();
if (driveLetter == this._driveLetter)
{
/* This is where we get the drive serial */
ManagementObjectSearcher disks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject disk in disks.Get())
{
if (disk["Name"].ToString() == ("\\\\.\\PHYSICALDRIVE" + driveNumber) & disk["InterfaceType"].ToString() == "USB")
{
this._serialNumber = parseSerialFromDeviceID(disk["PNPDeviceID"].ToString());
}
}
}
}
}
private string parseSerialFromDeviceID(string deviceId)
{
string[] splitDeviceId = deviceId.Split('\\');
string[] serialArray;
string serial;
int arrayLen = splitDeviceId.Length - 1;
serialArray = splitDeviceId[arrayLen].Split('&');
serial = serialArray[0];
return serial;
}
private string getValueInQuotes(string inValue)
{
string parsedValue = "";
int posFoundStart = 0;
int posFoundEnd = 0;
posFoundStart = inValue.IndexOf("\"");
posFoundEnd = inValue.IndexOf("\"", posFoundStart + 1);
parsedValue = inValue.Substring(posFoundStart + 1, (posFoundEnd - posFoundStart) - 1);
return parsedValue;
}
}
Related
I have currently wrote a code which scans the local network with a function called "bool ping()". I want to add a capability to provide basic device information when the function returns 'true'. I've found 'ManagementObjectSearcher'.
At first it looked perfect but when It gets used for a non-windows device it crash. Therefore I suppose that this method cannot be used for non-windows devices.
As I want to add the below code ( or login , after enough polishing ), to an android app that scans the local network and returns the
A) IP address and
B) (one of the following )
the device type ( desktop , laptop , smartphone)
and/or
the OS type ( android , windows , linux , tvOS )
Is there a valid way I can do what I am looking for? I believe I have experienced apps that do stuff like that, though I don't know what language they were based on.
namespace LanConsole
{
class Program
{
static void Main(string[] args)
{
string host = "192.168.1.10"; // android smartphone IP
string temp = null;
// arguments I found
string[] _searchClass = { "Win32_ComputerSystem", "Win32_OperatingSystem", "Win32_BaseBoard", "Win32_BIOS" };
string[] param = { "UserName", "Caption", "Product", "Description" };
bool v = ping(host, 10, 900); // bool function send ping to host
if (v == true)
{
Console.WriteLine("true");
for (int i = 0; i <= _searchClass.Length - 1; i++)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("\\\\" + host + "\\root\\CIMV2", "SELECT *FROM " + _searchClass[i]);
foreach (ManagementObject obj in searcher.Get())
{
temp += obj.GetPropertyValue(param[i]).ToString() + "\n";
if (i == _searchClass.Length - 1)
{
Console.WriteLine(temp, "Hostinfo: " + host);
break;
}
}
Console.WriteLine("");
}
}
else
Console.WriteLine("false");
}
public static bool ping(string host, int attempts, int timeout)
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply pingReply;
for (int i = 0; i < attempts; i++)
{
try
{
pingReply = ping.Send(host, timeout);
// If there is a successful ping, return true.
if (pingReply != null &&
pingReply.Status == System.Net.NetworkInformation.IPStatus.Success)
{
return true;
}
}
catch
{
// supressing errors
}
}
// Return false if ping fales "attempts" times
return false;
}
}
}
May be the title is duplicate. I am getting HDD of the laptop serial number successfully when no USB devices are connected. But when any USB is connected, the code gets the serial number of connected device. I only want the serial number of HDD of laptop or desktop even though USBs are connected.
Below is the code.
using System.Management;
namespace SystemInfo
{
public class Info1
{
public static String GetHDDSerialNo()
{
ManagementClass mangnmt = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection mcol = mangnmt.GetInstances();
string result = "";
foreach (ManagementObject strt in mcol)
{
result += Convert.ToString(strt["VolumeSerialNumber"]);
}
return result;
}
}
}
try this
ManagementObjectSearcher theSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE InterfaceType='USB'");
foreach (ManagementObject currentObject in theSearcher.Get())
{
ManagementObject theSerialNumberObjectQuery = new ManagementObject("Win32_PhysicalMedia.Tag='" + currentObject["DeviceID"] + "'");
MessageBox.Show(theSerialNumberObjectQuery["SerialNumber"].ToString());
}
You can use WMI Win32_DiskDrive, filter on MediaType containing "fixed" and get the SerialNumber
Something like :
public static String GetHDDSerialNo()
{
ManagementClass mangnmt = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection mcol = mangnmt.GetInstances();
string result = "";
foreach (ManagementObject strt in mcol)
{
if (Convert.ToString(strt["MediaType"]).ToUpper().Contains("FIXED"))
{
result += Convert.ToString(strt["SerialNumber"]);
}
}
return result;
}
Media type can contain "External", "Removable", "fixed". Exact string depends on OS. On Seven and XP, that String can be different. That's why we use Contains.
little reading
I've been trying to find a way to figure out which installed printers are 'connected'. After some Googling I figured I had to dive into WMI.
So I've built this test:
// Struct to store printer data in.
public struct MyPrinter
{
public string Availability;
public string ExtendedPrinterStatus;
public string Name;
public string PrinterStatus;
public string Status;
public string StatusInfo;
public MyPrinter(string a, string eps, string n, string ps, string s, string si)
{
Availability = a;
ExtendedPrinterStatus = eps;
Name = n;
PrinterStatus = ps;
Status = s;
StatusInfo = si;
}
}
var installedPrinters = new string[numPrinters];
PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
var data = new List<MyPrinter>();
foreach (var printer in searcher.Get())
{
if (installedPrinters.Contains(printer["Name"].ToString()))
{
var availability = (printer["Availability"] ?? "").ToString();
var extendedPrinterStatus = (printer["ExtendedPrinterStatus"] ?? "").ToString();
var name = (printer["Name"] ?? "").ToString();
var printerStatus = (printer["PrinterStatus"] ?? "").ToString();
var status = (printer["Status"] ?? "").ToString();
var statusInfo = (printer["StatusInfo"] ?? "").ToString();
data.Add(new MyPrinter(availability, extendedPrinterStatus, name, printerStatus, status, statusInfo));
}
}
I have 6 printers from which 2 are network printers. I've run this with all printers connected and all results looked like this:
Availability = "" // printer["Availability"] = null
ExtendedPrinterStatus = "2" // 2 = Unknown
Name = "{printer name here}"
PrinterStatus = "3" // 3 = Idle
Status = "Unknown"
StatusInfo = "" // Null
So the only difference between the printers is the name.
I ran the script again but this time I disconnected my laptop from the network. So 2 of the printers were not connected anymore in this case.
The strange thing (for me) is, the results were exactly the same.
The reason I ran this test is, to figure out which field I'd need to use for my case.
So at the end, I have not been able to figure out how to figure out if a printer is connected or not.
So what I'd like, is a way to figure out the installed + connected printers in C#. If there is a way to do it without the use of WMI classes, that's also fine by me, as long as it works.
Me and a colleague have tried lots of stuff to find a solution for this and we figured this worked:
private string[] GetAvailablePrinters()
{
var installedPrinters = new string[PrinterSettings.InstalledPrinters.Count];
PrinterSettings.InstalledPrinters.CopyTo(installedPrinters, 0);
var printers = new List<string>();
var printServers = new List<string>();
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer");
foreach (var printer in searcher.Get())
{
var serverName = #"\\" + printer["SystemName"].ToString().TrimStart('\\');
if (!printServers.Contains(serverName))
printServers.Add(serverName);
}
foreach (var printServer in printServers)
{
var server = new PrintServer(printServer);
try
{
var queues = server.GetPrintQueues();
printers.AddRange(queues.Select(q => q.Name));
}
catch (Exception)
{
// Handle exception correctly
}
}
return printers.ToArray();
}
The trick is that when a printserver is not available, GetPrintQueues will throw some specific exception. By only adding the printers that don't throw such an exception, we get a list of all the connected printers. This doesn't check if a printer is turned on/off because that actually doesn't matter. If it is turned off, the document will just be placed in the print queue and it can be printed later on.
I hope this helps others who bump into this problem.
Sidenote:
The reason I decided not to catch that specific exception, is because I would have to reference a dll just for that exception.
I'm looking for a way to determine if a COM is a standard COM or if it's an SPP COM, also known as a cable replacement bluetooth adapter for a COM device.
I have a device which works both in USB (COM -> USB) and Bluetooth, and the Bluetooth interface works with SPP.
I am currently using System.IO.Ports.SerialPort.GetPortNames() to get the COMs.
Is there a way to determine whether or not it's a connected with Bluetooth or USB?
SOLUTION:
System.Management.ManagementObjectSearcher Searcher = new System.Management.ManagementObjectSearcher("Select * from WIN32_SerialPort");
foreach (System.Management.ManagementObject Port in Searcher.Get())
{
foreach (System.Management.PropertyData Property in Port.Properties)
{
Console.WriteLine(Property.Name + " " + (Property.Value == null ? null : Property.Value.ToString()));
}
}
And the output is something similar:
Availability 2
Binary True
Capabilities
CapabilityDescriptions
Caption Standard Serial over Bluetooth link (COM10)
ConfigManagerErrorCode 0
ConfigManagerUserConfig False
CreationClassName Win32_SerialPort
Description Standard Serial over Bluetooth link
DeviceID COM10
ErrorCleared
ErrorDescription
InstallDate
LastErrorCode
MaxBaudRate 9600
MaximumInputBufferSize 0
MaximumOutputBufferSize 0
MaxNumberControlled
Name Standard Serial over Bluetooth link (COM10)
OSAutoDiscovered True
PNPDeviceID BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\8&3062A492&0&000000000000_0000001C
PowerManagementCapabilities System.UInt16[]
PowerManagementSupported False
ProtocolSupported
ProviderType RS232 Serial Port
SettableBaudRate True
SettableDataBits True
SettableFlowControl True
SettableParity True
SettableParityCheck False
SettableRLSD True
SettableStopBits True
Status OK
StatusInfo 3
Supports16BitMode False
SupportsDTRDSR True
SupportsElapsedTimeouts True
SupportsIntTimeouts True
SupportsParityCheck False
SupportsRLSD True
SupportsRTSCTS True
SupportsSpecialCharacters False
SupportsXOnXOff False
SupportsXOnXOffSet False
SystemCreationClassName Win32_ComputerSystem
SystemName JVALDRON-PC
TimeOfLastReset
You are unable to find this information out via the SerialPort class. You would need to do a WMI query.
Doing something along the lines of this may lead you to it
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select *
from WIN32_SerialPort");
foreach(ManagementObject Port in searcher.Get()) {
string a = (string) Port.GetPropertyValue("Name");
}
I haven't got this code loaded so I don't know what further properties you can obtain. However if there was anyway, WMI would be the way to do it.
I see your looking at a Bluetooth connected device:
Query the Win32_PnPSignedDriver and look at the InfName property. The value should be bthspp.inf
I cannot say with certainty that the inf file will ALWAYS be this name for every vendor's bluetooth device that supports SPP protocol, but this is the default.
Class GUID for COM & LPT ports is: {4d36e978-e325-11ce-bfc1-08002be10318}
Ref: https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426
ManagementObjectSearcher Searcher = new ManagementObjectSearcher( computer + #"root\cimv2",
"SELECT * FROM Win32_PnPSignedDriver "
+ "WHERE ClassGuid = '{4d36e978-e325-11ce-bfc1-08002be10318}' "
+ AND DeviceID LIKE 'BTHENUM%'
);
Maybe this helps somebody.
Code will return all available SPP Serialports.
public List<AvailableComPort> LoadAvailableComPorts()
{
List<AvailableComPort> serialComPortList = new List<AvailableComPort>();
using (var searcher = new ManagementObjectSearcher("SELECT * FROM WIN32_SerialPort"))
{
foreach (ManagementObject queryObj in searcher.Get())
{
if (queryObj["PNPDeviceID"] != null && queryObj["DeviceID"] != null)
{
//
// "BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\7&1ADE6D9D&1&0012F328A5A3_C00000000"
// => get only "0012F328A5A3" as ID
string pnpDeviceId = queryObj["PNPDeviceID"].ToString();
string id = pnpDeviceId.Split(new string[] { "\\" }, StringSplitOptions.None).LastOrDefault();
id = id.Split(new string[] { "&" }, StringSplitOptions.None).LastOrDefault();
id = id.Split(new string[] { "_" }, StringSplitOptions.None).FirstOrDefault();
if (serialComPortList.Where(o => o.Id == id).Count() == 0)
serialComPortList.Add(new AvailableComPort() { Id = id, ComPort = queryObj["DeviceID"].ToString() });
}
}
}
List<AvailableComPort> comPortAdvancedList = new List<AvailableComPort>();
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity"))
{
foreach (ManagementObject queryObj in searcher.Get())
{
if (queryObj["PNPDeviceID"] != null && queryObj["Name"] != null)
{
string pnpDeviceId = queryObj["PNPDeviceID"].ToString();
if (comPortAdvancedList.Where(o => o.Id == pnpDeviceId).Count() == 0)
comPortAdvancedList.Add(new AvailableComPort() { Id = pnpDeviceId, Name = queryObj["Name"].ToString() });
}
}
}
List<AvailableComPort> finalComPortList = new List<AvailableComPort>();
foreach (var serialComPort in serialComPortList)
{
AvailableComPort comPortAdvanced = comPortAdvancedList.Where(o => o.Id.Contains("DEV_" + serialComPort.Id)).FirstOrDefault();
if (comPortAdvanced != null)
{
comPortAdvanced.ComPort = serialComPort.ComPort;
finalComPortList.Add(comPortAdvanced);
}
}
return finalComPortList;
}
public class AvailableComPort
{
public string Id { get; set; }
public string ComPort { get; set; }
public string Name { get; set; }
}
I need in my program to tie a license to a hardware ID. I tried use WMI, but it still slow.
I need, for example, CPU, HDD, and motherboard info.
For more details refer to this link
The following code will give you CPU ID:
namespace required System.Management
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;
}
For Hard disk ID and motherboard id details refer this-link
To speed up this procedure, make sure you don't use SELECT *, but only select what you really need. Use SELECT * only during development when you try to find out what you need to use, because then the query will take much longer to complete.
I got here looking for the same thing and I found another solution. If you guys are interested I share this class:
using System;
using System.Management;
using System.Security.Cryptography;
using System.Security;
using System.Collections;
using System.Text;
namespace Security
{
/// <summary>
/// Generates a 16 byte Unique Identification code of a computer
/// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
/// </summary>
public class FingerPrint
{
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
{
}
}
}
}
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
{
}
}
}
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 won't take any credit for this because I found it here
It worked faster than I expected for me. Without the graphic card, mac and drive id's I got the unique ID in about 2-3 seconds. With those above included I got it in about 4-5 seconds.
Note: Add reference to System.Management.
The following approach was inspired by this answer to a related (more general) question.
The approach is to read the MachineGuid value in registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography. This value is generated during OS installation.
There are few ways around the uniqueness of the Hardware-ID per machine using this approach. One method is editing the registry value, but this would cause complications on the user's machine afterwards. Another method is to clone a drive image which would copy the MachineGuid value.
However, no approach is hack-proof and this will certainly be good enough for normal users. On the plus side, this approach is quick performance-wise and simple to implement.
public string GetMachineGuid()
{
string location = #"SOFTWARE\Microsoft\Cryptography";
string name = "MachineGuid";
using (RegistryKey localMachineX64View =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (RegistryKey rk = localMachineX64View.OpenSubKey(location))
{
if (rk == null)
throw new KeyNotFoundException(
string.Format("Key Not Found: {0}", location));
object machineGuid = rk.GetValue(name);
if (machineGuid == null)
throw new IndexOutOfRangeException(
string.Format("Index Not Found: {0}", name));
return machineGuid.ToString();
}
}
}
We use a combination of the processor id number (ProcessorID) from Win32_processor and the universally unique identifier (UUID) from Win32_ComputerSystemProduct:
ManagementObjectCollection mbsList = null;
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select ProcessorID From Win32_processor");
mbsList = mos.Get();
string processorId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
processorId = mo["ProcessorID"] as string;
}
mos = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct");
mbsList = mos.Get();
string systemId = string.Empty;
foreach (ManagementBaseObject mo in mbsList)
{
systemId = mo["UUID"] as string;
}
var compIdStr = $"{processorId}{systemId}";
Previously, we used a combination: processor ID ("Select ProcessorID From Win32_processor") and the motherboard serial number ("SELECT SerialNumber FROM Win32_BaseBoard"), but then we found out that the serial number of the motherboard may not be filled in, or it may be filled in with uniform values:
To be filled by O.E.M.
None
Default string
Therefore, it is worth considering this situation.
Also keep in mind that the ProcessorID number may be the same on different computers.
I have refactored Alex Sutu approach to be faster and simpler code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Security.Cryptography;
namespace Test
{
/// <summary>
/// Generates a Guid based on the current computer hardware
/// Example: C384B159-8E36-6C85-8ED8-6897486500FF
/// </summary>
public class SystemGuid
{
private static string _systemGuid = string.Empty;
public static string Value()
{
if (string.IsNullOrEmpty(_systemGuid))
{
var lCpuId = GetCpuId();
var lBiodId = GetBiosId();
var lMainboard = GetMainboardId();
var lGpuId = GetGpuId();
var lMac = GetMac();
var lConcatStr = $"CPU: {lCpuId}\nBIOS:{lBiodId}\nMainboard: {lMainboard}\nGPU: {lGpuId}\nMAC: {lMac}";
_systemGuid = GetHash(lConcatStr);
}
return _systemGuid;
}
private static string GetHash(string s)
{
try
{
var lProvider = new MD5CryptoServiceProvider();
var lUtf8 = lProvider.ComputeHash(ASCIIEncoding.UTF8.GetBytes(s));
return new Guid(lUtf8).ToString().ToUpper();
}
catch (Exception lEx)
{
return lEx.Message;
}
}
#region Original Device ID Getting Code
//Return a hardware identifier
private static string GetIdentifier(string pWmiClass, List<string> pProperties)
{
string lResult = string.Empty;
try
{
foreach (ManagementObject lItem in new ManagementClass(pWmiClass).GetInstances())
{
foreach (var lProperty in pProperties)
{
try
{
switch(lProperty)
{
case "MACAddress":
if (string.IsNullOrWhiteSpace(lResult) == false)
return lResult; //Return just the first MAC
if (lItem["IPEnabled"].ToString() != "True")
continue;
break;
}
var lItemProperty = lItem[lProperty];
if (lItemProperty == null)
continue;
var lValue = lItemProperty.ToString();
if (string.IsNullOrWhiteSpace(lValue) == false)
lResult += $"{lValue}; ";
}
catch { }
}
}
}
catch{}
return lResult.TrimEnd(' ', ';');
}
private static List<string> ListOfCpuProperties = new List<string>{ "UniqueId", "ProcessorId", "Name", "Manufacturer" };
private static string GetCpuId()
{
return GetIdentifier("Win32_Processor", ListOfCpuProperties);
}
private static List<string> ListOfBiosProperties = new List<string> { "Manufacturer", "SMBIOSBIOSVersion", "IdentificationCode", "SerialNumber", "ReleaseDate", "Version" };
//BIOS Identifier
private static string GetBiosId()
{
return GetIdentifier("Win32_BIOS", ListOfBiosProperties);
}
private static List<string> ListOfMainboardProperties = new List<string> { "Model", "Manufacturer", "Name", "SerialNumber" };
//Motherboard ID
private static string GetMainboardId()
{
return GetIdentifier("Win32_BaseBoard", ListOfMainboardProperties);
}
private static List<string> ListOfGpuProperties = new List<string> { "Name" };
//Primary video controller ID
private static string GetGpuId()
{
return GetIdentifier("Win32_VideoController", ListOfGpuProperties);
}
private static List<string> ListOfNetworkProperties = new List<string> { "MACAddress" };
private static string GetMac()
{
return GetIdentifier("Win32_NetworkAdapterConfiguration", ListOfNetworkProperties);
}
#endregion
}
}
Here is a DLL that shows:
* Hard drive ID (unique hardware serial number written in drive's IDE electronic chip)
* Partition ID (volume serial number)
* CPU ID (unique hardware ID)
* CPU vendor
* CPU running speed
* CPU theoretic speed
* Memory Load ( Total memory used in percentage (%) )
* Total Physical ( Total physical memory in bytes )
* Avail Physical ( Physical memory left in bytes )
* Total PageFile ( Total page file in bytes )
* Available PageFile( Page file left in bytes )
* Total Virtual( Total virtual memory in bytes )
* Available Virtual ( Virtual memory left in bytes )
* Bios unique identification numberBiosDate
* Bios unique identification numberBiosVersion
* Bios unique identification numberBiosProductID
* Bios unique identification numberBiosVideo
(text grabbed from original web site)
It works with C#.