I need to generate UUID for my Machine Mac address. Also i want extract the mac address from UUID.
I know we can use below two methods for encoding and decoding. But it will generate the encrypted string only not UUID.
Encode:
System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(plainTextBytes));
Decode:
System.Text.Encoding.UTF8.GetString(System.Convert.FromBase64String(base64EncodedData));
But for my requirement i want to generate(encode) the UUID and extract(decode) the mac address . How to do this in C# code?
You can get the MAC address using the following code.
From our tests it will return null on about 1.3% of machines (probably some form of virtual machine or something very locked down).
MAC Address of first IP enabled device
public static string GetMACAddress()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (ManagementObjectCollection moc = mc.GetInstances())
{
if (moc != null)
{
foreach (ManagementObject mo in moc)
{
try
{
Trace.WriteLine(mo["Index"] + " Mac " + mo["Caption"] + " : " + mo["MacAddress"] + " Enabled " + (bool)mo["IPEnabled"]);
if (mo["MacAddress"] != null && mo["IPEnabled"] != null && (bool)mo["IPEnabled"] == true)
{
return mo["MacAddress"].ToString();
}
}
finally
{
mo.Dispose();
}
}
}
}
}
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex.Message);
}
return null;
}
Related
I want to judge if the computer running my program is in a certain network.
I have tried the code below
ManagementClass vNetworkAdapter = new ManagementClass("Win32_NetworkAdapter");
ManagementObjectCollection vNetworkAdapters = vNetworkAdapter.GetInstances();
foreach (ManagementObject vNetworkAdapterInfo in vNetworkAdapters)
{
string ID = (string)vNetworkAdapterInfo.Properties["NetConnectionID"].Value;
string Caption = (string)vNetworkAdapterInfo.Properties["Caption"].Value;
string Description = (string)vNetworkAdapterInfo.Properties["Description"].Value;
string SSID = (string)vNetworkAdapterInfo.Properties["DeviceID"].Value;
if (ID != null)
{
if (ID == "以太网")//judge certain type of connection by name, I only considered the wired and wireless connection
{
Console.WriteLine("以太网" + "\n" + Caption + "\n" + Description);
Console.WriteLine(SSID);
}
else if (ID == "WLAN")
{
Console.WriteLine("WLAN" + "\n" + Caption + "\n" + Description);
Console.WriteLine(SSID);
}
}
Console.WriteLine("");
}
It returns With
WLAN
[00000002] Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)
Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)
以太网
[00000003] Killer E2500 Gigabit Ethernet Controller
Killer E2500 Gigabit Ethernet Controller
But I not wanting this name, I want to get the name shown when we are connecting to a certain network(known as SSID for wireless connection), What I should do? thanks a lot!
I have a problem connecting programmatically my device to a specific SSID.
In particular I noticed that:
If I connect manually the device to the SSID (Swipe down with my little finger, timid tap on the SSID), then my code to connect to that SSID work.
If the SSID is a new SSID that my device doesn't never connected before, then the code not works, but if connect manually work.
This is so strange, I can't figure out how to solve it.
I'm using Xamarin.Forms and Xamarin.Android, with Android 9.0 API 28 - Pie.
There is the code i use to (attempt to) connect:
public int ConnectToSSID(string SSID, string password)
{
var wifiConfiguration = new WifiConfiguration();
wifiConfiguration.Ssid = '"' + SSID + '"';
if (password.Length > 0)
{
wifiConfiguration.PreSharedKey = '"' + password + '"';
}
if (wifiManager == null)
{
wifiManager = (WifiManager)context.GetSystemService(Context.WifiService);
}
wifiManager.AddNetwork(wifiConfiguration);
IList<WifiConfiguration> list = wifiManager.ConfiguredNetworks;
foreach (WifiConfiguration conf in list)
{
if (conf.Ssid.Equals('"' + SSID +'"'))
{
wifiManager.Disconnect();
wifiManager.EnableNetwork(conf.NetworkId, true);
wifiManager.Reconnect();
return 1;
}
}
return 0;
}
To connect to a specific SSID programmatically, try using the following code.
string ssid = "\"" + _ssid + "\"";
string password = "\"" + _password + "\"";
var wifiConfig = new WifiConfiguration
{
Ssid = ssid,
PreSharedKey = password
};
var wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(WifiService);
var addNetwork = wifiManager.AddNetwork(wifiConfig);
var list = wifiManager.ConfiguredNetworks;
foreach (var wifiConfiguration in list)
{
if (wifiConfiguration.Ssid != null && WifiConfiguration.Ssid.Equals("\"" + _ssid + "\""))
{
wifiManager.Disconnect();
wifiManager.EnableNetwork(WifiConfiguration.NetworkId, true);
wifiManager.Reconnect();
break;
}
}
Ok I figured out what was the real problem: the WifiManager class fails to add a new WifiConfiguration.
Then the configuration was never picked from the ConfiguredNetworks list and never connect to it.
To solve this problem is necessary specify the security of the WifiConfiguration We want to connect to.
Be aware to the changes done to the APIs because the docs suggest to use:
WifiConfiguration conf = new WifiConfiguration();
conf.AllowedKeyManagement.Set(WifiConfiguration.[KEY_MANAGEMENT_CONST]);
But this doesn't work anymore, instead you have to use:
WifiConfiguration conf = new WifiConfiguration();
conf.AllowedKeyManagement.Set((int)KeyManagementType.[KEY_MANAGEMENT_CONST]);
Now my method to connect is:
public int ConnectToSSID(string SSID, string password)
{
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.Ssid = '"' + SSID + '"';
wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
wifiManager = (WifiManager)context.GetSystemService(Context.WifiService);
var addNet = wifiManager.AddNetwork(wifiConfiguration);
if (addNet == -1)
{
addNet = wifiManager.UpdateNetwork(wifiConfiguration);
}
if (addNet == -1)
{
return 0; //Error!
}
var list = wifiManager.ConfiguredNetworks;
foreach (WifiConfiguration conf in list)
{
if (conf.Ssid.Equals('"' + SSID + '"'))
{
wifiManager.Disconnect();
wifiManager.EnableNetwork(conf.NetworkId, true);
wifiManager.Reconnect();
return 1;
}
}
return 0;
}
Operating system patch
i want to get list of install patch of my operation system with version details in dot net,
i am trying using wmi
string Software = null;
string SoftwareKey = #"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
Software += "\r\nWINDOWS X64 Software\r\n\r\n\r\n ";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(SoftwareKey))
{
if (rk == null)
{
return Software;
}
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
if (!(sk.GetValue("DisplayName") == null))
{
if (sk.GetValue("InstallLocation") == null)
Software += sk.GetValue("DisplayName") + " - Install path not known \r\n ";
else
Software += sk.GetValue("DisplayName") + " - " + sk.GetValue("InstallLocation") + "\r\n ";
}
}
catch (Exception ex)
{
}
}
}
}
return Software;
This question already has answers here:
How to uniquely identify computer using C#?
(5 answers)
Closed 6 years ago.
I am working on a software lock using C#. I need to generate a unique number for every computer.
I have researched and decided to use the CPU number and hard drive number as a unique number for every computer.
My Code :
private string UniqID()
{
////////////////CpuID
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;
}
////////////////HDD ID
string drive = "C";
ManagementObject dsk = new ManagementObject(
#"win32_logicaldisk.deviceid=""" + drive + #":""");
dsk.Get();
string volumeSerial = dsk["VolumeSerialNumber"].ToString();
return volumeSerial + cpuInfo;
}
That works, but there is a problem!
When a user re-installs Windows (OS) and wants to run my software, the unique number has been changed.
Why does the unique number change when Windows is installed again? Do the CPU number and HDD number depend on the current windows installation?
You realistically have MotherboardID, CPUID, Disk Serial and MAC address, from experience none of them are 100%.
Our stats show
Disk serial Is missing 0.1 %
MAC Is missing 1.3 %
Motherboard ID Is missing 30 %
CPUID Is missing 99 %
0.04% of machines tested they yielded no information, we couldn't even read the computer name. It maybe that these were some kind over virtual PC, HyperV or VMWare instance?
Disk serial is the most reliable, but easy to change, mac can be changed and depending on the filtering applied can change if device drivers are added (hyperv, wireshark etc).
Motherboard and CPUID sometimes return values that are placeholders "NONE" etc.
You should also note that these functions can be very slow to call (they may take a few seconds even on a fast PC), so it may be worth kicking them off on a background thread as early as possible, you ideally don't want to be blocking on them.
Motherboard ID
private static void FetchMotherboardIdInternal()
{
try
{
ManagementScope scope = new ManagementScope("\\\\" + Environment.MachineName + "\\root\\cimv2");
scope.Connect();
using (ManagementObject wmiClass = new ManagementObject(scope, new ManagementPath("Win32_BaseBoard.Tag=\"Base Board\""), new ObjectGetOptions()))
{
object motherboardIDObj = wmiClass["SerialNumber"];
if (motherboardIDObj != null)
{
string motherboardID = motherboardIDObj.ToString().Trim();
Trace.WriteLine("MotherboardID = " + motherboardID);
if (IsValidMotherBoardID(motherboardID))
{
_motherboardID = motherboardID;
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read MotherbaordID\r\n" + ex.Message);
}
}
public static bool IsValidMotherBoardID(string value)
{
if (value == null)
return false;
string motherboardID = value.Trim();
return !( motherboardID.Replace(".", "").Replace(" ", "").Replace("\t", "").Trim().Length < 5 ||
motherboardID.ToUpper().Contains("BASE") ||
motherboardID.Contains("2345") ||
motherboardID.ToUpper().StartsWith("TO BE") ||
motherboardID.ToUpper().StartsWith("NONE") ||
motherboardID.ToUpper().StartsWith("N/A") ||
motherboardID.ToUpper().Contains("SERIAL") ||
motherboardID.ToUpper().Contains("OEM") ||
motherboardID.ToUpper().Contains("AAAAA") ||
motherboardID.ToUpper().Contains("ABCDE") ||
motherboardID.ToUpper().Contains("XXXXX") ||
motherboardID.ToUpper().Contains("NOT") ||
motherboardID.ToUpper().StartsWith("00000")
);
}
CPU ID
private static void FetchCpuIdInternal()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_Processor"))
{
using (ManagementObjectCollection moc = mc.GetInstances())
{
foreach (ManagementObject mo in moc)
{
if (mo.Properties["UniqueId"] != null && mo.Properties["UniqueId"].Value != null)
{
// only return cpuInfo from first CPU
Trace.WriteLine("CPU ID = " + mo.Properties["UniqueId"].Value.ToString());
_cpuID = mo.Properties["UniqueId"].Value.ToString();
}
mo.Dispose();
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read CPUID\r\n" + ex.Message);
}
}
MAC Adress of first card
private static void FecthMACAddressInternal()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
{
using (ManagementObjectCollection moc = mc.GetInstances())
{
if (moc != null)
{
foreach (ManagementObject mo in moc)
{
Trace.WriteLine(mo["Index"] + " Mac " + mo["Caption"] + " : " + mo["MacAddress"] + " Enabled " + (bool)mo["IPEnabled"]);
if (string.IsNullOrEmpty(_macAdderss)) // only return MAC Address from first card
{
if ( mo["MacAddress"] != null && mo["IPEnabled"] != null && (bool)mo["IPEnabled"] == true)
{
_macAdderss = mo["MacAddress"].ToString();
}
}
mo.Dispose();
}
}
}
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex.Message);
}
if (_macAdderss != null)
_macAdderss = _macAdderss.Replace(":", "");
}
Drive Serial Number
/// <summary>
/// return Volume Serial Number from hard drive
/// </summary>
/// <param name="strDriveLetter">[optional] Drive letter</param>
/// <returns>[string] VolumeSerialNumber</returns>
public static string GetVolumeSerial(char driveLetter)
{
try
{
using (ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid=\"" + driveLetter + ":\""))
{
if (disk == null)
return null;
disk.Get();
object diskObj = disk["VolumeSerialNumber"];
if (diskObj != null)
return diskObj.ToString();
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex.Message);
}
try
{
uint serialNum, serialNumLength, flags;
StringBuilder volumename = new StringBuilder(256);
StringBuilder fstype = new StringBuilder(256);
bool ok = GetVolumeInformation(driveLetter.ToString() + ":\\", volumename, (uint)volumename.Capacity - 1, out serialNum, out serialNumLength, out flags, fstype, (uint)fstype.Capacity - 1);
if (ok)
{
return string.Format("{0:X4}{1:X4}", serialNum >> 16, serialNum & 0xFFFF);
}
}
catch (System.Threading.ThreadAbortException)
{
throw;
}
catch (Exception ex2)
{
Trace.TraceWarning("Failed to read DiskID\r\n" + ex2.Message);
}
return null;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool GetVolumeInformation(string Volume, StringBuilder VolumeName, uint VolumeNameSize, out uint SerialNumber, out uint SerialNumberLength, out uint flags, StringBuilder fs, uint fs_size);
Using System.Management you can extract all Hardware information. with this you can create an ID from this values, meaby a crypted id and save it.
Here is a reference: Link
I use MAC Address, Motherboard id and works fine to me.
I hope this help!
I'm writing a part of a program that shall copy a batch of files from the current computer to a defined list of computers.
If these computers are not available, the code will hang for a long time trying to access them. Is there any functionallity in C# to check if the machine is available and then skip if it's not?
MFWs = File.ReadAllLines(GuiManager.MyConfigManagerConfig.MachinesList);
foreach (string MFW in MFWs)
{
if (MFW != System.Environment.MachineName)
{
String target = #"\\" + MFW + #"\D\IbSi\config\" + Path.GetFileName(ConfigFile);
String backup = #"\\" + MFW + #"\D\IbSi\userdata\" + Path.GetFileName(ConfigFile);
try
{
File.Copy(source, target, true);
File.Copy(source, backup, true);
}
catch (Exception ex)
{
Manager.SendMessage("Failed to copy " + Path.GetFileName(ConfigFile) + " to " + MFW + "\n" + ex.Message);
}
}
}
You could ping the computer before starting the copy (taken from this answer):
using System.Net.NetworkInformation;
public static bool IsHostAvailable(string nameOrAddress)
{
bool pingable = false;
Ping pinger = new Ping();
try
{
PingReply reply = pinger.Send(nameOrAddress);
pingable = reply.Status == IPStatus.Success;
}
catch (PingException)
{
// Discard PingExceptions and return false;
}
return pingable;
}
As noted in the comments you need to make sure the firewall on the servers is open for pings (ICMP echo requests)