diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 7213bcd..bec7e5b 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -9,7 +9,7 @@ assignees: ''
### Library version
-### OS & OS version
+### OS, version, architecture (32 bit / 64 bit)
### Describe the bug
README.md
- https://github.com/Jinjinov/Hardware.Info.git
- git
Computer;Device;Hardware;Info;Information;NET Standard;Windows;Linux;macOS
MIT
+ True
+ HardwareInfo.snk
+ true
+ true
@@ -33,8 +35,9 @@
-
-
+
+
+
diff --git a/Hardware.Info/HardwareInfo.cs b/Hardware.Info/HardwareInfo.cs
index bf9c9e5..8cecca4 100644
--- a/Hardware.Info/HardwareInfo.cs
+++ b/Hardware.Info/HardwareInfo.cs
@@ -8,27 +8,98 @@
namespace Hardware.Info
{
+ ///
+ /// Main Hardware.Info class
+ ///
public class HardwareInfo : IHardwareInfo
{
+ ///
+ /// Operating system
+ ///
public OS OperatingSystem { get; private set; } = new OS();
+
+ ///
+ /// Memory status
+ ///
public MemoryStatus MemoryStatus { get; private set; } = new MemoryStatus();
+ ///
+ /// List of
+ ///
public List BatteryList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List BiosList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
+ public List ComputerSystemList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List CpuList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List DriveList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List KeyboardList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List MemoryList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List MonitorList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List MotherboardList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List MouseList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List NetworkAdapterList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List PrinterList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List SoundDeviceList { get; private set; } = new List();
+
+ ///
+ /// List of
+ ///
public List VideoControllerList { get; private set; } = new List();
private readonly IHardwareInfoRetrieval _hardwareInfoRetrieval = null!;
+ ///
+ /// Main Hardware.Info class
+ ///
+ /// causes WMI queries to use SELECT * FROM instead of SELECT with a list of property names
+ /// sets the Timeout property of the EnumerationOptions in the ManagementObjectSearcher that executes the query. The default value is EnumerationOptions.InfiniteTimeout
public HardwareInfo(bool useAsteriskInWMI = true, TimeSpan? timeoutInWMI = null)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // Environment.OSVersion.Platform == PlatformID.Win32NT)
@@ -47,6 +118,9 @@ public HardwareInfo(bool useAsteriskInWMI = true, TimeSpan? timeoutInWMI = null)
}
}
+ ///
+ /// Refresh all hardware info
+ ///
public void RefreshAll()
{
RefreshOperatingSystem();
@@ -54,6 +128,7 @@ public void RefreshAll()
RefreshBatteryList();
RefreshBIOSList();
+ RefreshComputerSystemList();
RefreshCPUList();
RefreshDriveList();
RefreshKeyboardList();
@@ -67,21 +142,89 @@ public void RefreshAll()
RefreshVideoControllerList();
}
+ ///
+ /// Refresh operating system info
+ ///
public void RefreshOperatingSystem() => OperatingSystem = _hardwareInfoRetrieval.GetOperatingSystem();
+
+ ///
+ /// Refresh memory status info
+ ///
public void RefreshMemoryStatus() => MemoryStatus = _hardwareInfoRetrieval.GetMemoryStatus();
+ ///
+ /// Refresh battery info
+ ///
public void RefreshBatteryList() => BatteryList = _hardwareInfoRetrieval.GetBatteryList();
+
+ ///
+ /// Refresh BIOS info
+ ///
public void RefreshBIOSList() => BiosList = _hardwareInfoRetrieval.GetBiosList();
- public void RefreshCPUList(bool includePercentProcessorTime = true) => CpuList = _hardwareInfoRetrieval.GetCpuList(includePercentProcessorTime);
+
+ ///
+ /// Refresh computer system info
+ ///
+ public void RefreshComputerSystemList() => ComputerSystemList = _hardwareInfoRetrieval.GetComputerSystemList();
+
+ ///
+ /// Refresh CPU info
+ ///
+ /// Include PercentProcessorTime info. This makes the method a bit slower.
+ /// Delay in milliseconds between two measurements in Linux
+ public void RefreshCPUList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500) => CpuList = _hardwareInfoRetrieval.GetCpuList(includePercentProcessorTime, millisecondsDelayBetweenTwoMeasurements);
+
+ ///
+ /// Refresh drive info
+ ///
public void RefreshDriveList() => DriveList = _hardwareInfoRetrieval.GetDriveList();
+
+ ///
+ /// Refresh keyboard info
+ ///
public void RefreshKeyboardList() => KeyboardList = _hardwareInfoRetrieval.GetKeyboardList();
+
+ ///
+ /// Refresh memory info
+ ///
public void RefreshMemoryList() => MemoryList = _hardwareInfoRetrieval.GetMemoryList();
+
+ ///
+ /// Refresh monitor info
+ ///
public void RefreshMonitorList() => MonitorList = _hardwareInfoRetrieval.GetMonitorList();
+
+ ///
+ /// Refresh motherboard info
+ ///
public void RefreshMotherboardList() => MotherboardList = _hardwareInfoRetrieval.GetMotherboardList();
+
+ ///
+ /// Refresh mouse info
+ ///
public void RefreshMouseList() => MouseList = _hardwareInfoRetrieval.GetMouseList();
- public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true) => NetworkAdapterList = _hardwareInfoRetrieval.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration);
+
+ ///
+ /// Refresh network adapter info
+ ///
+ /// Include BytesPerSec info. This makes the method a bit slower.
+ /// Include NetworkAdapterConfiguration info. This makes the method a bit slower.
+ /// Delay in milliseconds between two measurements in Linux
+ public void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000) => NetworkAdapterList = _hardwareInfoRetrieval.GetNetworkAdapterList(includeBytesPerSec, includeNetworkAdapterConfiguration, millisecondsDelayBetweenTwoMeasurements);
+
+ ///
+ /// Refresh printer info
+ ///
public void RefreshPrinterList() => PrinterList = _hardwareInfoRetrieval.GetPrinterList();
+
+ ///
+ /// Refresh sound device info
+ ///
public void RefreshSoundDeviceList() => SoundDeviceList = _hardwareInfoRetrieval.GetSoundDeviceList();
+
+ ///
+ /// Refresh video controller info
+ ///
public void RefreshVideoControllerList() => VideoControllerList = _hardwareInfoRetrieval.GetVideoControllerList();
#region Static
@@ -89,6 +232,11 @@ public void RefreshAll()
private static bool _pingInProgress;
private static Action? _onPingComplete;
+ ///
+ /// Ping
+ ///
+ /// Host name or address to ping
+ /// On ping complete callback with "bool success" parameter
public static void Ping(string hostNameOrAddress, Action onPingComplete)
{
if (_pingInProgress)
@@ -132,6 +280,10 @@ private static void PingCompleted(object sender, PingCompletedEventArgs e)
_onPingComplete?.Invoke(success);
}
+ ///
+ /// Get local IPv4 addresses
+ ///
+ /// Local IPv4 addresses
public static IEnumerable GetLocalIPv4Addresses()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
@@ -147,6 +299,11 @@ public static IEnumerable GetLocalIPv4Addresses()
}
}
+ ///
+ /// Get local IPv4 addresses
+ ///
+ /// Filter by NetworkInterfaceType
+ /// Local IPv4 addresses
public static IEnumerable GetLocalIPv4Addresses(NetworkInterfaceType networkInterfaceType)
{
return NetworkInterface.GetAllNetworkInterfaces()
@@ -156,6 +313,11 @@ public static IEnumerable GetLocalIPv4Addresses(NetworkInterfaceType
.Select(addressInformation => addressInformation.Address);
}
+ ///
+ /// Get local IPv4 addresses
+ ///
+ /// Filter by OperationalStatus
+ /// Local IPv4 addresses
public static IEnumerable GetLocalIPv4Addresses(OperationalStatus operationalStatus)
{
return NetworkInterface.GetAllNetworkInterfaces()
@@ -165,6 +327,12 @@ public static IEnumerable GetLocalIPv4Addresses(OperationalStatus ope
.Select(addressInformation => addressInformation.Address);
}
+ ///
+ /// Get local IPv4 addresses
+ ///
+ /// Filter by NetworkInterfaceType
+ /// Filter by OperationalStatus
+ /// Local IPv4 addresses
public static IEnumerable GetLocalIPv4Addresses(NetworkInterfaceType networkInterfaceType, OperationalStatus operationalStatus)
{
return NetworkInterface.GetAllNetworkInterfaces()
diff --git a/Hardware.Info/HardwareInfo.snk b/Hardware.Info/HardwareInfo.snk
new file mode 100644
index 0000000..23136f9
Binary files /dev/null and b/Hardware.Info/HardwareInfo.snk differ
diff --git a/Hardware.Info/HardwareInfoBase.cs b/Hardware.Info/HardwareInfoBase.cs
index e0b6c16..cef9ed7 100644
--- a/Hardware.Info/HardwareInfoBase.cs
+++ b/Hardware.Info/HardwareInfoBase.cs
@@ -89,18 +89,24 @@ public virtual List GetDriveList()
foreach (DriveInfo driveInfo in DriveInfo.GetDrives())
{
- Volume volume = new Volume
+ try
{
- FileSystem = driveInfo.DriveFormat,
- Description = driveInfo.DriveType.ToString(),
- Name = driveInfo.Name,
- Caption = driveInfo.RootDirectory.FullName,
- FreeSpace = (ulong)driveInfo.TotalFreeSpace,
- Size = (ulong)driveInfo.TotalSize,
- VolumeName = driveInfo.VolumeLabel
- };
-
- partition.VolumeList.Add(volume);
+ Volume volume = new Volume
+ {
+ FileSystem = driveInfo.DriveFormat,
+ Description = driveInfo.DriveType.ToString(),
+ Name = driveInfo.Name,
+ Caption = driveInfo.RootDirectory.FullName,
+ FreeSpace = (ulong)driveInfo.TotalFreeSpace,
+ Size = (ulong)driveInfo.TotalSize,
+ VolumeName = driveInfo.VolumeLabel
+ };
+
+ partition.VolumeList.Add(volume);
+ }
+ catch (UnauthorizedAccessException)
+ {
+ }
}
drive.PartitionList.Add(partition);
@@ -110,7 +116,7 @@ public virtual List GetDriveList()
return driveList;
}
- public virtual List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true)
+ public virtual List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000)
{
List networkAdapterList = new List();
diff --git a/Hardware.Info/IHardwareInfo.cs b/Hardware.Info/IHardwareInfo.cs
index cba9470..7084551 100644
--- a/Hardware.Info/IHardwareInfo.cs
+++ b/Hardware.Info/IHardwareInfo.cs
@@ -2,42 +2,179 @@
namespace Hardware.Info
{
+ ///
+ /// Main Hardware.Info interface
+ ///
public interface IHardwareInfo
{
+ ///
+ /// Operating system
+ ///
OS OperatingSystem { get; }
+
+ ///
+ /// Memory status
+ ///
MemoryStatus MemoryStatus { get; }
+ ///
+ /// List of
+ ///
List BatteryList { get; }
+
+ ///
+ /// List of
+ ///
List BiosList { get; }
+
+ ///
+ /// List of
+ ///
+ List ComputerSystemList { get; }
+
+ ///
+ /// List of
+ ///
List CpuList { get; }
+
+ ///
+ /// List of
+ ///
List DriveList { get; }
+
+ ///
+ /// List of
+ ///
List KeyboardList { get; }
+
+ ///
+ /// List of
+ ///
List MemoryList { get; }
+
+ ///
+ /// List of
+ ///
List MonitorList { get; }
+
+ ///
+ /// List of
+ ///
List MotherboardList { get; }
+
+ ///
+ /// List of
+ ///
List MouseList { get; }
+
+ ///
+ /// List of
+ ///
List NetworkAdapterList { get; }
+
+ ///
+ /// List of
+ ///
List PrinterList { get; }
+
+ ///
+ /// List of
+ ///
List SoundDeviceList { get; }
+
+ ///
+ /// List of
+ ///
List VideoControllerList { get; }
+ ///
+ /// Refresh all hardware info
+ ///
void RefreshAll();
+ ///
+ /// Refresh operating system info
+ ///
void RefreshOperatingSystem();
+
+ ///
+ /// Refresh memory status info
+ ///
void RefreshMemoryStatus();
+ ///
+ /// Refresh battery info
+ ///
void RefreshBatteryList();
+
+ ///
+ /// Refresh BIOS info
+ ///
void RefreshBIOSList();
- void RefreshCPUList(bool includePercentProcessorTime = true);
+
+ ///
+ /// Refresh computer system info
+ ///
+ void RefreshComputerSystemList();
+
+ ///
+ /// Refresh CPU info
+ ///
+ /// Include PercentProcessorTime info. This makes the method a bit slower.
+ /// Delay in milliseconds between two measurements in Linux
+ void RefreshCPUList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500);
+
+ ///
+ /// Refresh drive info
+ ///
void RefreshDriveList();
+
+ ///
+ /// Refresh keyboard info
+ ///
void RefreshKeyboardList();
+
+ ///
+ /// Refresh memory info
+ ///
void RefreshMemoryList();
+
+ ///
+ /// Refresh monitor info
+ ///
void RefreshMonitorList();
+
+ ///
+ /// Refresh motherboard info
+ ///
void RefreshMotherboardList();
+
+ ///
+ /// Refresh mouse info
+ ///
void RefreshMouseList();
- void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true);
+
+ ///
+ /// Refresh network adapter info
+ ///
+ /// Include BytesPerSec info. This makes the method a bit slower.
+ /// Include NetworkAdapterConfiguration info. This makes the method a bit slower.
+ /// Delay in milliseconds between two measurements in Linux
+ void RefreshNetworkAdapterList(bool includeBytesPerSec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000);
+
+ ///
+ /// Refresh printer info
+ ///
void RefreshPrinterList();
+
+ ///
+ /// Refresh sound device info
+ ///
void RefreshSoundDeviceList();
+
+ ///
+ /// Refresh video controller info
+ ///
void RefreshVideoControllerList();
}
}
\ No newline at end of file
diff --git a/Hardware.Info/IHardwareInfoRetrieval.cs b/Hardware.Info/IHardwareInfoRetrieval.cs
index b71e604..2d2c8cd 100644
--- a/Hardware.Info/IHardwareInfoRetrieval.cs
+++ b/Hardware.Info/IHardwareInfoRetrieval.cs
@@ -9,14 +9,15 @@ internal interface IHardwareInfoRetrieval
List GetBatteryList();
List GetBiosList();
- List GetCpuList(bool includePercentProcessorTime = true);
+ List GetComputerSystemList();
+ List GetCpuList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500);
List GetDriveList();
List GetKeyboardList();
List GetMemoryList();
List GetMonitorList();
List GetMotherboardList();
List GetMouseList();
- List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true);
+ List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000);
List GetPrinterList();
List GetSoundDeviceList();
List GetVideoControllerList();
diff --git a/Hardware.Info/Linux/HardwareInfoRetrieval.cs b/Hardware.Info/Linux/HardwareInfoRetrieval.cs
index 5067e5f..6d81935 100644
--- a/Hardware.Info/Linux/HardwareInfoRetrieval.cs
+++ b/Hardware.Info/Linux/HardwareInfoRetrieval.cs
@@ -1,13 +1,12 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
-using System.Net.NetworkInformation;
using System.Net;
+using System.Net.NetworkInformation;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
-using System.Globalization;
-using System.Net.Sockets;
// https://www.binarytides.com/linux-commands-hardware-info/
@@ -146,34 +145,99 @@ public List GetBiosList()
return biosList;
}
- public List GetCpuList(bool includePercentProcessorTime = true)
+ public List GetComputerSystemList()
{
- List cpuList = new List();
+ List computerSystemList = new List();
+
+ ComputerSystem computerSystem = new ComputerSystem
+ {
+ Caption = TryReadTextFromFile("/sys/class/dmi/id/product_name"),
+ Description = TryReadTextFromFile("/sys/class/dmi/id/product_family"),
+ IdentifyingNumber = TryReadTextFromFile("/sys/class/dmi/id/product_serial"),
+ Name = TryReadTextFromFile("/sys/class/dmi/id/product_name"),
+ SKUNumber = TryReadTextFromFile("/sys/class/dmi/id/product_sku"),
+ UUID = TryReadTextFromFile("/sys/class/dmi/id/product_uuid"),
+ Vendor = TryReadTextFromFile("/sys/class/dmi/id/sys_vendor"),
+ Version = TryReadTextFromFile("/sys/class/dmi/id/product_version")
+ };
+ computerSystemList.Add(computerSystem);
+
+ return computerSystemList;
+ }
+
+ private class Processor
+ {
+ public string ProcessorId = string.Empty;
+ public string VendorId = string.Empty;
+ public string ModelName = string.Empty;
+ public uint CpuMhz;
+ public uint CacheSize;
+ public uint PhysicalId;
+ public uint Siblings;
+ public uint CoreId;
+ public uint CpuCores;
+
+ public uint L1DataCacheSize;
+ public uint L1InstructionCacheSize;
+ public uint L2CacheSize;
+ public uint L3CacheSize;
+
+ public ulong PercentProcessorTime;
+ }
+
+ public List GetCpuList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500)
+ {
string[] lines = TryReadLinesFromFile("/proc/cpuinfo");
+ Regex processorRegex = new Regex(@"^processor\s+:\s+(\d+)"); // processor ID (from 0 to 7 in a PC with two quad core CPUs)
Regex vendorIdRegex = new Regex(@"^vendor_id\s+:\s+(.+)");
Regex modelNameRegex = new Regex(@"^model name\s+:\s+(.+)");
Regex cpuSpeedRegex = new Regex(@"^cpu MHz\s+:\s+(.+)");
- Regex cacheSizeRegex = new Regex(@"^cache size\s+:\s+(.+)\s+KB");
- Regex physicalCoresRegex = new Regex(@"^cpu cores\s+:\s+(.+)");
- Regex logicalCoresRegex = new Regex(@"^siblings\s+:\s+(.+)");
+ Regex cacheSizeRegex = new Regex(@"^cache size\s+:\s+(.+)\s+KB"); // L2 cache size in KB
+ Regex physicalIdRegex = new Regex(@"^physical id\s+:\s+(\d+)"); // physical CPU ID (a PC with two quad core CPUs, 4 cores will have one value, and the other 4 will have another value)
+ Regex logicalCoresRegex = new Regex(@"^siblings\s+:\s+(.+)"); // number of logical cores (no hyperthreading = same as physical, with hyperthreading = 2 * physical)
+ Regex coreIdRegex = new Regex(@"^core id\s+:\s+(.+)"); // core ID (from 0 to 3 in a PC with two quad core CPUs - for the first CPU, and then the same for second CPU)
+ Regex physicalCoresRegex = new Regex(@"^cpu cores\s+:\s+(.+)"); // number of cores (in a quad core CPU = 4)
- CPU cpu = new CPU();
+ List processorList = new List();
+
+ Processor processor = null!;
foreach (string line in lines)
{
- Match match = vendorIdRegex.Match(line);
+ Match match = processorRegex.Match(line);
+ if (match.Success && match.Groups.Count > 1)
+ {
+ processor = new Processor();
+
+ if (uint.TryParse(match.Groups[1].Value, out uint processorId))
+ {
+ processor.ProcessorId = $"cpu{processorId}";
+
+ GetCpuCacheSize(processor);
+
+ processorList.Add(processor);
+ }
+ continue;
+ }
+
+ if (processor == null)
+ {
+ continue;
+ }
+
+ match = vendorIdRegex.Match(line);
if (match.Success && match.Groups.Count > 1)
{
- cpu.Manufacturer = match.Groups[1].Value.Trim();
+ processor.VendorId = match.Groups[1].Value.Trim();
continue;
}
match = modelNameRegex.Match(line);
if (match.Success && match.Groups.Count > 1)
{
- cpu.Name = match.Groups[1].Value.Trim();
+ processor.ModelName = match.Groups[1].Value.Trim();
continue;
}
@@ -181,7 +245,7 @@ public List GetCpuList(bool includePercentProcessorTime = true)
if (match.Success && match.Groups.Count > 1)
{
if (double.TryParse(match.Groups[1].Value, out double currentClockSpeed))
- cpu.CurrentClockSpeed = (uint)currentClockSpeed;
+ processor.CpuMhz = (uint)currentClockSpeed;
continue;
}
@@ -189,15 +253,15 @@ public List GetCpuList(bool includePercentProcessorTime = true)
if (match.Success && match.Groups.Count > 1)
{
if (uint.TryParse(match.Groups[1].Value, out uint cacheSize))
- cpu.L3CacheSize = 1024 * cacheSize;
+ processor.CacheSize = 1024 * cacheSize;
continue;
}
- match = physicalCoresRegex.Match(line);
+ match = physicalIdRegex.Match(line);
if (match.Success && match.Groups.Count > 1)
{
- if (uint.TryParse(match.Groups[1].Value, out uint numberOfCores))
- cpu.NumberOfCores = numberOfCores;
+ if (uint.TryParse(match.Groups[1].Value, out uint physicalId))
+ processor.PhysicalId = physicalId;
continue;
}
@@ -205,16 +269,82 @@ public List GetCpuList(bool includePercentProcessorTime = true)
if (match.Success && match.Groups.Count > 1)
{
if (uint.TryParse(match.Groups[1].Value, out uint numberOfLogicalProcessors))
- cpu.NumberOfLogicalProcessors = numberOfLogicalProcessors;
+ processor.Siblings = numberOfLogicalProcessors;
+ continue;
+ }
+
+ match = coreIdRegex.Match(line);
+ if (match.Success && match.Groups.Count > 1)
+ {
+ if (uint.TryParse(match.Groups[1].Value, out uint coreId))
+ processor.CoreId = coreId;
+ continue;
+ }
+
+ match = physicalCoresRegex.Match(line);
+ if (match.Success && match.Groups.Count > 1)
+ {
+ if (uint.TryParse(match.Groups[1].Value, out uint numberOfCores))
+ processor.CpuCores = numberOfCores;
continue;
}
}
+ ulong percentProcessorTime = 0;
+
+ if (includePercentProcessorTime)
+ {
+ percentProcessorTime = GetCpuUsage(processorList, millisecondsDelayBetweenTwoMeasurements);
+ }
+
+ List cpuList = new List();
+
+ foreach (var group in processorList.GroupBy(processor => processor.PhysicalId))
+ {
+ Processor first = group.First();
+
+ CPU cpu = new CPU
+ {
+ PercentProcessorTime = percentProcessorTime,
+ ProcessorId = group.Key.ToString(),
+ Manufacturer = first.VendorId,
+ Name = first.ModelName,
+ CurrentClockSpeed = first.CpuMhz,
+ NumberOfLogicalProcessors = first.Siblings,
+ NumberOfCores = first.CpuCores,
+ L1DataCacheSize = first.L1DataCacheSize,
+ L1InstructionCacheSize = first.L1InstructionCacheSize,
+ L2CacheSize = first.L2CacheSize,
+ L3CacheSize = first.L3CacheSize
+ };
+
+ if (cpu.L2CacheSize == 0)
+ cpu.L2CacheSize = first.CacheSize;
+
+ foreach (Processor proc in group)
+ {
+ CpuCore core = new CpuCore
+ {
+ Name = proc.ProcessorId,
+ PercentProcessorTime = proc.PercentProcessorTime
+ };
+
+ cpu.CpuCoreList.Add(core);
+ }
+
+ cpuList.Add(cpu);
+ }
+
+ return cpuList;
+ }
+
+ private static void GetCpuCacheSize(Processor processor)
+ {
for (int i = 0; i <= 3; i++)
{
- string level = TryReadTextFromFile($"/sys/devices/system/cpu/cpu0/cache/index{i}/level");
- string type = TryReadTextFromFile($"/sys/devices/system/cpu/cpu0/cache/index{i}/type");
- string size = TryReadTextFromFile($"/sys/devices/system/cpu/cpu0/cache/index{i}/size");
+ string level = TryReadTextFromFile($"/sys/devices/system/cpu/{processor.ProcessorId}/cache/index{i}/level");
+ string type = TryReadTextFromFile($"/sys/devices/system/cpu/{processor.ProcessorId}/cache/index{i}/type");
+ string size = TryReadTextFromFile($"/sys/devices/system/cpu/{processor.ProcessorId}/cache/index{i}/size");
if (uint.TryParse(size.TrimEnd('K'), out uint cacheSize))
{
@@ -223,31 +353,22 @@ public List GetCpuList(bool includePercentProcessorTime = true)
if (level == "1")
{
if (type == "Data")
- cpu.L1DataCacheSize = cacheSize;
+ processor.L1DataCacheSize = cacheSize;
if (type == "Instruction")
- cpu.L1InstructionCacheSize = cacheSize;
+ processor.L1InstructionCacheSize = cacheSize;
}
if (level == "2")
- cpu.L2CacheSize = cacheSize;
+ processor.L2CacheSize = cacheSize;
if (level == "3")
- cpu.L3CacheSize = cacheSize;
+ processor.L3CacheSize = cacheSize;
}
}
-
- if (includePercentProcessorTime)
- {
- GetCpuUsage(cpu);
- }
-
- cpuList.Add(cpu);
-
- return cpuList;
}
- private static void GetCpuUsage(CPU cpu)
+ private static ulong GetCpuUsage(List processorList, int millisecondsDelayBetweenTwoMeasurements)
{
// Column Name Description
// 1 user Time spent with normal processing in user mode.
@@ -268,30 +389,28 @@ private static void GetCpuUsage(CPU cpu)
// ...
string[] cpuUsageLineLast = TryReadLinesFromFile("/proc/stat");
- Task.Delay(500).Wait();
+ Task.Delay(millisecondsDelayBetweenTwoMeasurements).Wait();
string[] cpuUsageLineNow = TryReadLinesFromFile("/proc/stat");
+ ulong percentProcessorTime = 0;
+
if (cpuUsageLineLast.Length > 0 && cpuUsageLineNow.Length > 0)
{
- cpu.PercentProcessorTime = GetCpuPercentage(cpuUsageLineLast[0], cpuUsageLineNow[0]);
+ percentProcessorTime = GetCpuPercentage(cpuUsageLineLast[0], cpuUsageLineNow[0]);
- for (int i = 0; i < cpu.NumberOfLogicalProcessors; i++)
+ foreach (Processor processor in processorList)
{
- string? cpuStatLast = cpuUsageLineLast.FirstOrDefault(s => s.StartsWith($"cpu{i}"));
- string? cpuStatNow = cpuUsageLineNow.FirstOrDefault(s => s.StartsWith($"cpu{i}"));
+ string? cpuStatLast = cpuUsageLineLast.FirstOrDefault(s => s.StartsWith(processor.ProcessorId));
+ string? cpuStatNow = cpuUsageLineNow.FirstOrDefault(s => s.StartsWith(processor.ProcessorId));
if (!string.IsNullOrEmpty(cpuStatLast) && !string.IsNullOrEmpty(cpuStatNow))
{
- CpuCore core = new CpuCore
- {
- Name = i.ToString(),
- PercentProcessorTime = GetCpuPercentage(cpuStatLast, cpuStatNow)
- };
-
- cpu.CpuCoreList.Add(core);
+ processor.PercentProcessorTime = GetCpuPercentage(cpuStatLast, cpuStatNow);
}
}
}
+
+ return percentProcessorTime;
}
private static UInt64 GetCpuPercentage(string cpuStatLast, string cpuStatNow)
@@ -325,6 +444,11 @@ private static UInt64 GetCpuPercentage(string cpuStatLast, string cpuStatNow)
// Get the delta between two reads
ulong cpuDelta = cpuSumNow - cpuSumLast;
+ if (cpuDelta == 0)
+ {
+ return 0; // avoid System.DivideByZeroException: Attempted to divide by zero.
+ }
+
// Get the idle time Delta
ulong cpuIdle = 0;
@@ -344,7 +468,7 @@ private static UInt64 GetCpuPercentage(string cpuStatLast, string cpuStatNow)
public override List GetDriveList()
{
- List driveList = new List();
+ List driveList = base.GetDriveList();
string processOutput = ReadProcessOutput("lshw", "-class disk");
@@ -356,19 +480,18 @@ public override List GetDriveList()
{
string trimmed = line.Trim();
- if (trimmed.StartsWith("*-"))
+ if (trimmed.StartsWith("*-cdrom") || trimmed.StartsWith("*-disk"))
{
- if (disk != null)
+ if(driveList.Count > 0 && disk == null && trimmed.StartsWith("*-disk"))
{
+ disk = driveList.First();
+ }
+ else
+ {
+ disk = new Drive();
driveList.Add(disk);
}
- disk = null;
- }
-
- if (trimmed.StartsWith("*-cdrom") || trimmed.StartsWith("*-disk"))
- {
- disk = new Drive();
continue;
}
@@ -382,15 +505,54 @@ public override List GetDriveList()
{
disk.Manufacturer = trimmed.Replace("vendor:", string.Empty).Trim();
}
+ else if (trimmed.StartsWith("description:"))
+ {
+ disk.Description = trimmed.Replace("description:", string.Empty).Trim();
+ }
+ else if (trimmed.StartsWith("version:"))
+ {
+ disk.FirmwareRevision = trimmed.Replace("version:", string.Empty).Trim();
+ }
+ else if (trimmed.StartsWith("logical name:"))
+ {
+ disk.Name = trimmed.Replace("logical name:", string.Empty).Trim();
+ }
+ else if (trimmed.StartsWith("serial:"))
+ {
+ disk.SerialNumber = trimmed.Replace("serial:", string.Empty).Trim();
+ }
+ else if (trimmed.StartsWith("size:"))
+ {
+ string size = trimmed.Replace("size:", string.Empty).Trim();
+ disk.Size = ExtractSizeInBytes(size);
+ }
}
}
- if (disk != null)
+ return driveList;
+
+ static ulong ExtractSizeInBytes(string input)
{
- driveList.Add(disk);
- }
+ Regex regex = new Regex(@"(\d+)\s*(KB|MB|GB|TB)");
+ Match match = regex.Match(input);
- return driveList;
+ if (match.Success)
+ {
+ if (ulong.TryParse(match.Groups[1].Value, out ulong size))
+ {
+ return match.Groups[2].Value switch
+ {
+ "KB" => size * 1024UL,
+ "MB" => size * 1024UL * 1024UL,
+ "GB" => size * 1024UL * 1024UL * 1024UL,
+ "TB" => size * 1024UL * 1024UL * 1024UL * 1024UL,
+ _ => size,
+ };
+ }
+ }
+
+ return 0;
+ }
}
public List GetKeyboardList()
@@ -660,7 +822,7 @@ private List GetNetworkAdapters()
Caption = interfaceName,
Description = interfaceName,
Name = interfaceName,
- MACAddress = macAddress,
+ MACAddress = macAddress.Replace(":", "").ToUpper(),
NetConnectionID = interfaceName,
ProductName = interfaceName,
};
@@ -753,25 +915,16 @@ private bool TryGetInterfaceIp(string[] fibTrieLines, string network, out string
return foundIp;
}
- public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true)
+ public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000)
{
- List networkAdapterList;
-
- try
- {
- networkAdapterList = base.GetNetworkAdapterList(includeBytesPersec, includeNetworkAdapterConfiguration);
- }
- catch (NetworkInformationException)
- {
- networkAdapterList = GetNetworkAdapters();
- }
+ List networkAdapterList = GetNetworkAdapters();
if (includeBytesPersec)
{
char[] charSeparators = new char[] { ' ' };
string[] procNetDevLast = TryReadLinesFromFile("/proc/net/dev");
- Task.Delay(1000).Wait();
+ Task.Delay(millisecondsDelayBetweenTwoMeasurements).Wait();
string[] procNetDevNow = TryReadLinesFromFile("/proc/net/dev");
foreach (NetworkAdapter networkAdapter in networkAdapterList)
@@ -1025,7 +1178,7 @@ 1680x1050 59.88
lines = processOutput.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- foreach (string line in lines.Where(l => l.Contains("VGA compatible controller")))
+ foreach (string line in lines.Where(l => l.Contains("VGA compatible controller") || l.Contains("3D controller") || l.Contains("Display controller")))
{
string[] split = line.Split(':');
diff --git a/Hardware.Info/Mac/HardwareInfoRetrieval.cs b/Hardware.Info/Mac/HardwareInfoRetrieval.cs
index 0e38500..ff24c63 100644
--- a/Hardware.Info/Mac/HardwareInfoRetrieval.cs
+++ b/Hardware.Info/Mac/HardwareInfoRetrieval.cs
@@ -326,6 +326,73 @@ public List GetBiosList()
return biosList;
}
+ /*
+ system_profiler SPHardwareDataType
+Hardware:
+
+ Hardware Overview:
+
+ Model Name: Mac mini
+ Model Identifier: Macmini9,1
+ Model Number: MGNR3ZE/A
+ Chip: Apple M1
+ Total Number of Cores: 8 (4 performance and 4 efficiency)
+ Memory: 8 GB
+ System Firmware Version: 10151.140.19
+ OS Loader Version: 10151.140.19
+ Serial Number (system): C07JG1XTQ6NV
+ Hardware UUID: A7C8F6C7-C339-5904-B220-CF4C3D22FB1B
+ Provisioning UDID: 00008103-001965521E60801E
+ Activation Lock Status: Enabled
+ */
+
+ public List GetComputerSystemList()
+ {
+ List computerSystemList = new List();
+
+ ComputerSystem computerSystem = new ComputerSystem
+ {
+ Vendor = "Apple"
+ };
+
+ StartProcess("system_profiler", "SPHardwareDataType",
+ standardOutput =>
+ {
+ string line = standardOutput.Trim();
+
+ if (line.StartsWith("Model Name: "))
+ {
+ computerSystem.Caption = line.Replace("Model Name: ", string.Empty);
+ computerSystem.Name = line.Replace("Model Name: ", string.Empty);
+ }
+ else if (line.StartsWith("Model Identifier: "))
+ {
+ computerSystem.Description = line.Replace("Model Identifier: ", string.Empty);
+ }
+ else if (line.StartsWith("Serial Number (system): "))
+ {
+ computerSystem.IdentifyingNumber = line.Replace("Serial Number (system): ", string.Empty);
+ }
+ else if (line.StartsWith("Model Number: "))
+ {
+ computerSystem.SKUNumber = line.Replace("Model Number: ", string.Empty);
+ }
+ else if (line.StartsWith("Hardware UUID: "))
+ {
+ computerSystem.UUID = line.Replace("Hardware UUID: ", string.Empty);
+ }
+ else if (line.StartsWith("System Firmware Version: "))
+ {
+ computerSystem.Version = line.Replace("System Firmware Version: ", string.Empty);
+ }
+ },
+ standardError => { });
+
+ computerSystemList.Add(computerSystem);
+
+ return computerSystemList;
+ }
+
/*
SPHardwareDataType
Hardware:
@@ -346,7 +413,7 @@ Serial Number (system): 0
Hardware UUID: F6D9C340-725A-224A-8855-99AB8348F745
/**/
- public List GetCpuList(bool includePercentProcessorTime = true)
+ public List GetCpuList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500)
{
List cpuList = new List();
@@ -420,7 +487,7 @@ public override List GetDriveList()
VBOX HARDDISK:
Capacity: 536,87 GB (536.870.912.000 bytes)
- Model: VBOX HARDDISK
+ Model: VBOX HARDDISK
Revision: 1,000000
Serial Number: VBa308df62-62a2d2a0
Native Command Queuing: Yes
@@ -464,9 +531,9 @@ public override List GetDriveList()
VBOX CD-ROM:
- Model: VBOX CD-ROM
+ Model: VBOX CD-ROM
Revision: 1,000000
- Serial Number: VB1-1a2b3c4d
+ Serial Number: VB1-1a2b3c4d
Native Command Queuing: No
Detachable Drive: No
Power Off: No
@@ -871,7 +938,7 @@ Extra Operating Current (mA): 0
return mouseList;
}
- public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true)
+ public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000)
{
/*
SPNetworkDataType
diff --git a/Hardware.Info/Windows/HardwareInfoRetrieval.cs b/Hardware.Info/Windows/HardwareInfoRetrieval.cs
index 203ac7d..0668a3f 100644
--- a/Hardware.Info/Windows/HardwareInfoRetrieval.cs
+++ b/Hardware.Info/Windows/HardwareInfoRetrieval.cs
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
using System.Management;
using System.Net;
using System.Runtime.InteropServices;
using System.Security;
+using System.Text;
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
@@ -42,6 +44,7 @@ internal class HardwareInfoRetrieval : HardwareInfoBase, IHardwareInfoRetrieval
public bool UseAsteriskInWMI { get; set; }
private readonly string _managementScope = "root\\cimv2";
+ private readonly string _managementScopeWmi = "root\\wmi";
private readonly EnumerationOptions _enumerationOptions = new EnumerationOptions() { ReturnImmediately = true, Rewindable = false, Timeout = EnumerationOptions.InfiniteTimeout };
public HardwareInfoRetrieval(TimeSpan? enumerationOptionsTimeout = null)
@@ -162,6 +165,26 @@ public static string GetPropertyString(object obj)
return (obj is string str) ? str : string.Empty;
}
+ public static string GetStringFromUInt16Array(ushort[] array)
+ {
+ try
+ {
+ if (array.Length == 0)
+ return string.Empty;
+
+ byte[] byteArray = new byte[array.Length * 2];
+ Buffer.BlockCopy(array, 0, byteArray, 0, byteArray.Length);
+
+ string str = Encoding.Unicode.GetString(byteArray).Trim('\0');
+
+ return str;
+ }
+ catch
+ {
+ return string.Empty;
+ }
+ }
+
// https://docs.microsoft.com/en-us/dotnet/api/system.management.managementpath.defaultpath?view=netframework-4.8
public List GetBatteryList()
@@ -221,7 +244,35 @@ public List GetBiosList()
return biosList;
}
- public List GetCpuList(bool includePercentProcessorTime = true)
+ public List GetComputerSystemList()
+ {
+ List computerSystemList = new List();
+
+ string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_ComputerSystemProduct"
+ : "SELECT Caption, Description, IdentifyingNumber, Name, SKUNumber, UUID, Vendor, Version FROM Win32_ComputerSystemProduct";
+ using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _enumerationOptions);
+
+ foreach (ManagementBaseObject mo in mos.Get())
+ {
+ ComputerSystem computerSystem = new ComputerSystem
+ {
+ Caption = GetPropertyString(mo["Caption"]),
+ Description = GetPropertyString(mo["Description"]),
+ IdentifyingNumber = GetPropertyString(mo["IdentifyingNumber"]),
+ Name = GetPropertyString(mo["Name"]),
+ SKUNumber = GetPropertyString(mo["SKUNumber"]),
+ UUID = GetPropertyString(mo["UUID"]),
+ Vendor = GetPropertyString(mo["Vendor"]),
+ Version = GetPropertyString(mo["Version"])
+ };
+
+ computerSystemList.Add(computerSystem);
+ }
+
+ return computerSystemList;
+ }
+
+ public List GetCpuList(bool includePercentProcessorTime = true, int millisecondsDelayBetweenTwoMeasurements = 500)
{
List cpuList = new List();
@@ -511,22 +562,47 @@ public List GetMonitorList()
{
List monitorList = new List();
- string queryString = UseAsteriskInWMI ? "SELECT * FROM Win32_DesktopMonitor WHERE PNPDeviceID IS NOT NULL"
- : "SELECT Caption, Description, MonitorManufacturer, MonitorType, Name, PixelsPerXLogicalInch, PixelsPerYLogicalInch FROM Win32_DesktopMonitor WHERE PNPDeviceID IS NOT NULL";
- using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _enumerationOptions);
+ string win32PnpEntityQuery = UseAsteriskInWMI ? "SELECT * FROM Win32_PnPEntity WHERE PNPClass='Monitor'"
+ : "SELECT DeviceId FROM Win32_PnPEntity WHERE PNPClass='Monitor'";
+ using ManagementObjectSearcher win32PnpEntityMos = new ManagementObjectSearcher(_managementScope, win32PnpEntityQuery, _enumerationOptions);
- foreach (ManagementBaseObject mo in mos.Get())
+ foreach (ManagementBaseObject win32PnpEntityMo in win32PnpEntityMos.Get())
{
- Monitor monitor = new Monitor
+ string deviceId = GetPropertyString(win32PnpEntityMo["DeviceId"]);
+ string win32DesktopMonitorQuery = UseAsteriskInWMI ? $"SELECT * FROM Win32_DesktopMonitor WHERE PNPDeviceId='{deviceId}'"
+ : $"SELECT Caption, Description, MonitorManufacturer, MonitorType, Name, PixelsPerXLogicalInch, PixelsPerYLogicalInch FROM Win32_DesktopMonitor WHERE PNPDeviceId='{deviceId}'";
+ using ManagementObjectSearcher win32DesktopMonitorMos = new ManagementObjectSearcher(_managementScope, win32DesktopMonitorQuery.Replace(@"\", @"\\"), _enumerationOptions);
+
+ string wmiMonitorIdQuery = UseAsteriskInWMI ? $"SELECT * FROM WmiMonitorID WHERE InstanceName LIKE '{deviceId}%'"
+ : $"SELECT Active, ProductCodeID, SerialNumberID, ManufacturerName, UserFriendlyName, WeekOfManufacture, YearOfManufacture FROM WmiMonitorID WHERE InstanceName LIKE '{deviceId}%'";
+ using ManagementObjectSearcher wmiMonitorIdMos = new ManagementObjectSearcher(_managementScopeWmi, wmiMonitorIdQuery.Replace(@"\", "_"), _enumerationOptions);
+
+ using ManagementBaseObject? desktopMonitorMo = win32DesktopMonitorMos.Get().Cast().FirstOrDefault();
+ using ManagementBaseObject? wmiMonitorIdMo = wmiMonitorIdMos.Get().Cast().FirstOrDefault();
+
+ Monitor monitor = new Monitor();
+
+ if (desktopMonitorMo != null)
{
- Caption = GetPropertyString(mo["Caption"]),
- Description = GetPropertyString(mo["Description"]),
- MonitorManufacturer = GetPropertyString(mo["MonitorManufacturer"]),
- MonitorType = GetPropertyString(mo["MonitorType"]),
- Name = GetPropertyString(mo["Name"]),
- PixelsPerXLogicalInch = GetPropertyValue(mo["PixelsPerXLogicalInch"]),
- PixelsPerYLogicalInch = GetPropertyValue(mo["PixelsPerYLogicalInch"])
- };
+ monitor.Caption = GetPropertyString(desktopMonitorMo["Caption"]);
+ monitor.Description = GetPropertyString(desktopMonitorMo["Description"]);
+ monitor.MonitorManufacturer = GetPropertyString(desktopMonitorMo["MonitorManufacturer"]);
+ monitor.MonitorType = GetPropertyString(desktopMonitorMo["MonitorType"]);
+ monitor.Name = GetPropertyString(desktopMonitorMo["Name"]);
+ monitor.PixelsPerXLogicalInch = GetPropertyValue(desktopMonitorMo["PixelsPerXLogicalInch"]);
+ monitor.PixelsPerYLogicalInch = GetPropertyValue(desktopMonitorMo["PixelsPerYLogicalInch"]);
+ }
+
+ if (wmiMonitorIdMo != null)
+ {
+ monitor.Active = GetPropertyValue(wmiMonitorIdMo["Active"]);
+ monitor.ProductCodeID = GetStringFromUInt16Array(GetPropertyArray(wmiMonitorIdMo["ProductCodeID"]));
+ monitor.UserFriendlyName = GetStringFromUInt16Array(GetPropertyArray(wmiMonitorIdMo["UserFriendlyName"]));
+ monitor.SerialNumberID = GetStringFromUInt16Array(GetPropertyArray(wmiMonitorIdMo["SerialNumberID"]));
+ monitor.ManufacturerName = GetStringFromUInt16Array(GetPropertyArray(wmiMonitorIdMo["ManufacturerName"]));
+ monitor.WeekOfManufacture = GetPropertyValue(wmiMonitorIdMo["WeekOfManufacture"]);
+ monitor.YearOfManufacture = GetPropertyValue(wmiMonitorIdMo["YearOfManufacture"]);
+ }
monitorList.Add(monitor);
}
@@ -582,7 +658,7 @@ public List GetMouseList()
return mouseList;
}
- public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true)
+ public override List GetNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true, int millisecondsDelayBetweenTwoMeasurements = 1000)
{
List networkAdapterList = new List();
diff --git a/README.md b/README.md
index 3f54b60..6c60f64 100644
--- a/README.md
+++ b/README.md
@@ -7,34 +7,44 @@ Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor,
1. Include NuGet package from https://www.nuget.org/packages/Hardware.Info
-
+
2. Call `RefreshAll()` or one of the other `Refresh*()` methods:
class Program
{
- static readonly IHardwareInfo hardwareInfo = new HardwareInfo();
+ static IHardwareInfo hardwareInfo;
static void Main(string[] _)
{
- //hardwareInfo.RefreshOperatingSystem();
- //hardwareInfo.RefreshMemoryStatus();
- //hardwareInfo.RefreshBatteryList();
- //hardwareInfo.RefreshBIOSList();
- //hardwareInfo.RefreshCPUList();
- //hardwareInfo.RefreshDriveList();
- //hardwareInfo.RefreshKeyboardList();
- //hardwareInfo.RefreshMemoryList();
- //hardwareInfo.RefreshMonitorList();
- //hardwareInfo.RefreshMotherboardList();
- //hardwareInfo.RefreshMouseList();
- //hardwareInfo.RefreshNetworkAdapterList();
- //hardwareInfo.RefreshPrinterList();
- //hardwareInfo.RefreshSoundDeviceList();
- //hardwareInfo.RefreshVideoControllerList();
-
- hardwareInfo.RefreshAll();
+ try
+ {
+ hardwareInfo = new HardwareInfo();
+
+ //hardwareInfo.RefreshOperatingSystem();
+ //hardwareInfo.RefreshMemoryStatus();
+ //hardwareInfo.RefreshBatteryList();
+ //hardwareInfo.RefreshBIOSList();
+ //hardwareInfo.RefreshComputerSystemList();
+ //hardwareInfo.RefreshCPUList();
+ //hardwareInfo.RefreshDriveList();
+ //hardwareInfo.RefreshKeyboardList();
+ //hardwareInfo.RefreshMemoryList();
+ //hardwareInfo.RefreshMonitorList();
+ //hardwareInfo.RefreshMotherboardList();
+ //hardwareInfo.RefreshMouseList();
+ //hardwareInfo.RefreshNetworkAdapterList();
+ //hardwareInfo.RefreshPrinterList();
+ //hardwareInfo.RefreshSoundDeviceList();
+ //hardwareInfo.RefreshVideoControllerList();
+
+ hardwareInfo.RefreshAll();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
Console.WriteLine(hardwareInfo.OperatingSystem);
@@ -46,6 +56,9 @@ Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor,
foreach (var hardware in hardwareInfo.BiosList)
Console.WriteLine(hardware);
+ foreach (var hardware in hardwareInfo.ComputerSystemList)
+ Console.WriteLine(hardware);
+
foreach (var cpu in hardwareInfo.CpuList)
{
Console.WriteLine(cpu);
@@ -54,8 +67,6 @@ Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor,
Console.WriteLine(cpuCore);
}
- Console.ReadLine();
-
foreach (var drive in hardwareInfo.DriveList)
{
Console.WriteLine(drive);
@@ -69,8 +80,6 @@ Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor,
}
}
- Console.ReadLine();
-
foreach (var hardware in hardwareInfo.KeyboardList)
Console.WriteLine(hardware);
@@ -98,8 +107,6 @@ Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor,
foreach (var hardware in hardwareInfo.VideoControllerList)
Console.WriteLine(hardware);
- Console.ReadLine();
-
foreach (var address in HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Ethernet, OperationalStatus.Up))
Console.WriteLine(address);
@@ -136,6 +143,10 @@ You can avoid the 21 second delay by excluding the queries that cause it (see Se
Sometimes `NetworkAdapter.Speed` in `Win32_NetworkAdapter` can be `0` or `long.MaxValue`. The correct value can be retrived from `CurrentBandwidth` in `Win32_PerfFormattedData_Tcpip_NetworkAdapter` but unfortunately reading from `Win32_PerfFormattedData_Tcpip_NetworkAdapter` causes a 21 second delay on the first read, like mentioned in the previous paragraph. Calling `RefreshNetworkAdapterList` with `includeBytesPersec = true` will also read the `CurrentBandwidth`.
+### `WmiNetUtilsHelper` will throw an exception in Windows if publish settings use `true`
+
+This is a known error: https://github.com/dotnet/core/issues/7051#issuecomment-1071484354
+
## Settings
### Constructor settings:
@@ -146,16 +157,32 @@ HardwareInfo(bool useAsteriskInWMI = true, TimeSpan? timeoutInWMI = null)
The construcotr accepts two settings for WMI:
- `useAsteriskInWMI` causes WMI queries to use `SELECT * FROM` instead of `SELECT` with a list of property names. This is slower, but safer, more compatible with older Windows (XP, Vista, 7, 8) where a certain WMI property might be missing and throw an exception when queried by name. The default value is `true`.
-- `timeoutInWMI` sets the `Timeout` property of the `EnumerationOptions` in the `ManagementObjectSearcher` that executes the query. The default value is `EnumerationOptions.InfiniteTimeout`. Changing this could cause the query to return empty results in certain cases.
+- `timeoutInWMI` sets the `Timeout` property of the `EnumerationOptions` in the `ManagementObjectSearcher` that executes each query. The default value is `EnumerationOptions.InfiniteTimeout`. There are one or more queries for each hardware component, so there are more than 16 queries executed on `RefreshAll()`. If a query reaches the timeout it will throw a `System.Management.ManagementException` exception where `ErrorCode` will be `System.Management.ManagementStatus.Timedout`. If you set the `timeoutInWMI` then use a `try-catch` block like this:
-### Refresh methods settings:
+ IHardwareInfo hardwareInfo;
-In these two methods you can exclude some slow queries by setting the parameters to `false`:
+ try
+ {
+ hardwareInfo = new HardwareInfo(timeoutInWMI: TimeSpan.FromMilliseconds(100));
-```
-RefreshCPUList(bool includePercentProcessorTime = true)
+ hardwareInfo.RefreshAll();
+ }
+ catch (ManagementException ex) when (ex.ErrorCode == ManagementStatus.Timedout)
+ {
+ Console.WriteLine(ex);
+ }
+
+### Refresh methods settings:
-RefreshNetworkAdapterList(bool includeBytesPersec = true, bool includeNetworkAdapterConfiguration = true)
+```
+RefreshCPUList(
+ bool includePercentProcessorTime = true,
+ int millisecondsDelayBetweenTwoMeasurements = 500)
+
+RefreshNetworkAdapterList(
+ bool includeBytesPersec = true,
+ bool includeNetworkAdapterConfiguration = true,
+ int millisecondsDelayBetweenTwoMeasurements = 1000)
```
Setting `includePercentProcessorTime` and `includeBytesPersec` to `false` will exclude the queries that:
@@ -164,6 +191,24 @@ Setting `includePercentProcessorTime` and `includeBytesPersec` to `false` will e
Setting `includeNetworkAdapterConfiguration` to `false` has only a small impact on performance.
+Delay in milliseconds between two measurements in Linux:
+
+For `PercentProcessorTime` in Linux:
+```
+string[] cpuUsageLineLast = TryReadLinesFromFile("/proc/stat");
+Task.Delay(millisecondsDelayBetweenTwoMeasurements).Wait();
+string[] cpuUsageLineNow = TryReadLinesFromFile("/proc/stat");
+```
+If `includePercentProcessorTime` is false, `millisecondsDelayBetweenTwoMeasurements` has no effect.
+
+For `BytesSentPersec` and `BytesReceivedPersec` in Linux:
+```
+string[] procNetDevLast = TryReadLinesFromFile("/proc/net/dev");
+Task.Delay(millisecondsDelayBetweenTwoMeasurements).Wait();
+string[] procNetDevNow = TryReadLinesFromFile("/proc/net/dev");
+```
+If `includeBytesPersec` is false, `millisecondsDelayBetweenTwoMeasurements` has no effect.
+
## Benchmarks
### Windows 8.1 (Intel i5-2500, 8 GB RAM):
@@ -207,6 +252,38 @@ Setting `includeNetworkAdapterConfiguration` to `false` has only a small impact
## Version history:
+- 101.0.0.0
+ - Fixed `GetCpuList` in Linux - thanks to [@inelisoni](https://github.com/inelisoni)
+ - Added `int millisecondsDelayBetweenTwoMeasurements` to `GetCpuList`
+ - Added `int millisecondsDelayBetweenTwoMeasurements` to `GetNetworkAdapterList`
+- 100.1.1.1
+ - Fixed `GetNetworkAdapterList` in Linux - thanks to [@Pregath0r](https://github.com/Pregath0r)
+- 100.1.1.0
+ - Added `ComputerSystem` info in Windows, macOS, Linux - thanks to [@Zagrthos](https://github.com/Zagrthos)
+- 100.1.0.1
+ - Fixed `GetVideoControllerList` in Linux - thanks to [@NogginBops](https://github.com/NogginBops)
+- 100.1.0.0
+ - Fixed `GetDriveList` in Linux - thanks to [@GusanoGris](https://github.com/GusanoGris)
+ - Added `Microsoft.SourceLink.GitHub` - by [@andreas-eriksson](https://github.com/andreas-eriksson)
+- 100.0.1.1
+ - Added XML documentation - thanks to [@andreas-eriksson](https://github.com/andreas-eriksson)
+- 100.0.1.0
+ - Added `Disk.Description` in Linux
+ - Added `Disk.FirmwareRevision` in Linux
+ - Added `Disk.Name` in Linux
+ - Added `Disk.SerialNumber` in Linux
+ - Added `Disk.Size` in Linux
+- 100.0.0.1
+ - Added `HardwareInfo.snk` to sign the assembly with a strong name key
+- 100.0.0.0
+ - Fixed `GetCpuList` in Linux - thanks to [@inelisoni](https://github.com/inelisoni)
+- 11.1.1.1
+ - Fixed `GetMonitorList` in Windows - by [@Geevo](https://github.com/Geevo)
+- 11.1.1.0
+ - Fixed `GetMonitorList` in Windows - by [@Geevo](https://github.com/Geevo)
+- 11.1.0.1
+ - Fixed `GetNetworkAdapterList` in Linux - thanks to [@Nihlus](https://github.com/Nihlus)
+ - Fixed `GetCpuList` in Windows - by [@Frooxius](https://github.com/Frooxius)
- 11.1.0.0
- Fixed `NetworkAdapter.Speed` in Windows - by [@isenmann](https://github.com/isenmann)
- 11.0.1.1