Code Monkey home page Code Monkey logo

jinjinov / hardware.info Goto Github PK

View Code? Open in Web Editor NEW
438.0 14.0 76.0 229 KB

Battery, BIOS, CPU - processor, storage drive, keyboard, RAM - memory, monitor, motherboard, mouse, NIC - network adapter, printer, sound card - audio card, graphics card - video card. Hardware.Info is a .NET Standard 2.0 library and uses WMI on Windows, /dev, /proc, /sys on Linux and sysctl, system_profiler on macOS.

License: MIT License

C# 100.00%
computer device hardware info information net-standard windows linux macos

hardware.info's People

Contributors

240026763 avatar davidaramant avatar frooxius avatar geevo avatar isenmann avatar jesperll avatar jinjinov avatar reptail avatar schotime avatar tadelsucht avatar

Stargazers

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

Watchers

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

hardware.info's Issues

Use in Raspberry Pi

I have tried to get this nuget package in a Raspberry Pi 4, but it always fails.

I do it using: dotnet add package Hardware.Info

I was wondering if this should work? Or if it has been tested in a Raspberry Pi device?

Network speed is set to 0 or set to long.MaxValue in certain circumstances

Library version

11.0.1.1

OS & OS version

Windows 11

Describe the bug

There are two scenarios when the network speed is displayed incorrect:

  1. If no network cable is plugged in, the network speed is set to long.MaxValue. Better would be 0 which can be read in the Win32_PerfFormattedData_Tcpip_NetworkAdapter
  2. If there is no Speed value at all in Win32_NetworkAdapter, the value is set to default of long which is 0. But the correct value is available in Win32_PerfFormattedData_Tcpip_NetworkAdapter

As you can see the network speed is set to long.MaxValue because the network card isn't plugged in at all, which you can see in the NetConnectionStatus is set to 7
SpeedMax

And in this network adapter there is no speed at all which leads to a value of 0 because GetPropertyValue returns the default. But if you read the network speed from Win32_PerfFormattedData_Tcpip_NetworkAdapter the value is set correctly there, so as fallback you could read that value.
SpeedNotAvailable

Expected behavior

The network speed should displayed correctly and shoudl not be misleading

Use semantic versioning for package releases

Is your feature request related to a problem? Please describe.
At the moment, the library appears to use some type of binary-encoded version for each of its releases. Generally, it's more useful for downstream users of the library if the release version is somewhat descriptive of the changes made to the library from the previous version to this one.

Describe the solution you'd like
Most software libraries use semantic versioning for its releases, indicating compatibility changes in the components of each version release (major is breaking, minor is new features, patch is a pure fix without any functionality changes). It would be nice if Hardware.Info also used this system.

https://semver.org/

`WmiNetUtilsHelper` exception if `PublishTrimmed` is `true`

Library version

11.1.0.0

OS & OS version

Windows 11 22H2

Describe the bug

The type initializer for 'System.Management.WmiNetUtilsHelper' threw an exception.
System.TypeInitializationException
System.Management
Boolean IsNoContextMTA()
   at System.Management.MTAHelper.IsNoContextMTA()
   at System.Management.MTAHelper.CreateInMTA(Type)
   at System.Management.ManagementPath.CreateWbemPath(String)
   at System.Management.ManagementPath..ctor(String path)
   at System.Management.ManagementScope..ctor(String path)
   at System.Management.ManagementObjectSearcher..ctor(String, String, EnumerationOptions)
   at Hardware.Info.Windows.HardwareInfoRetrieval.GetOs()
   at Hardware.Info.Windows.HardwareInfoRetrieval..ctor(Nullable`1 enumerationOptionsTimeout)
   at Hardware.Info.HardwareInfo..ctor(Boolean useAsteriskInWMI, Nullable`1 timeoutInWMI)

Publish setting:

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net7.0\publish\win-x64\</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <_TargetId>Folder</_TargetId>
    <TargetFramework>net7.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishReadyToRun>true</PublishReadyToRun>
    <PublishTrimmed>true</PublishTrimmed>
  </PropertyGroup>
</Project>

if PublishTrimmed is true threw exception.
if PublishTrimmed is false , Program is ok

CPU usage

Is your feature request related to a problem? Please describe.
I'm often frustrated because I need a way to calculate CPU usage, but I'm unsure of the best approach.

Describe the solution you'd like
I would like a straightforward method for obtaining the CPU usage percentage of the system, whether it's through a specific library, API, or another means.

Describe alternatives you've considered
I've considered using the System.Diagnostics.PerformanceCounter class to retrieve CPU usage, but I'm also interested in knowing if there are other, more convenient methods available.

Additional context
I'm developing a monitoring tool that requires real-time CPU usage data. I'd like to find a solution that is cross-platform as my application will run on different operating systems.

Please provide additional context or requirements if needed, so that I can better understand your request and offer more detailed assistance.

Curious about AOT compilation

Hi sir, sorry this is not a bug, just curious about this lib even works fine with AOT mode, because System.Management is obviously not compatible with AOT mode: dotnet/runtime#61960
so what magic did you use, sir?
and thanks~

Check if the current account has permissions to use WMI

Is your feature request related to a problem? Please describe.
Is it possible to create a method to check if the user account/current account has permissions to use WMI? Or during initialization throw an exception indicating the same?

Describe the solution you'd like
A method or an exception while initializing the class indicating the user does not have permissions to use WMI

Describe alternatives you've considered
None yet.

Additional context
None.

Network interfaces cannot be refreshed when the available address families are restricted with systemd

Library version

11.1.0

OS & OS version

Ubuntu 20.04
systemd 245

Describe the bug

When attempting to refresh and query network devices while running as a systemd service with the hardening option RestrictAddressFamilies set to AF_INET AF_INET6, the library fails to enumerate the available interfaces with an exception.

Removing this option resolves the issue.

To Reproduce

Steps to reproduce the behavior:

  1. Compile the program below.
  2. Run the program as a systemd service with RestrictAddressFamilies set to AF_INET AF_INET6
using Hardware.Info;

var hardwareInfo = new HardwareInfo();
hardwareInfo.RefreshAll();

Exceptions (if any)

Jun 10 11:35:36 Remora.Neos.Headless[649931]: Unhandled exception. System.Net.NetworkInformation.NetworkInformationException (0x80004005): Success
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at System.Net.NetworkInformation.LinuxNetworkInterface.GetLinuxNetworkInterfaces()
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Hardware.Info.HardwareInfoBase.GetNetworkAdapterList(Boolean includeBytesPersec, Boolean includeNetworkAdapterConfiguration)
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Hardware.Info.Linux.HardwareInfoRetrieval.GetNetworkAdapterList(Boolean includeBytesPersec, Boolean includeNetworkAdapterConfiguration)
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Hardware.Info.HardwareInfo.RefreshNetworkAdapterList(Boolean includeBytesPerSec, Boolean includeNetworkAdapterConfiguration)
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Hardware.Info.HardwareInfo.RefreshAll()
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Program.<Main>$(String[] args)
Jun 10 11:35:36 Remora.Neos.Headless[649931]:    at Program.<Main>(String[] args)

Expected behavior

Network interfaces should be successfully enumerated.

Incorrent CPU information for multiprocessor platforms on Linux

Library version

11.1.1.1

OS, version, architecture (32 bit / 64 bit)

Ubuntu 22.04.3 LTS, Linux 5.15.0-78-generic

Describe the bug

The CPU list always contains only one CPU, even on multiprocessor platforms.

To Reproduce

On multiprocessor platform following code

using Hardware.Info;

var hardwareInfo = new HardwareInfo(useAsteriskInWMI: false);
hardwareInfo.RefreshCPUList(includePercentProcessorTime: false);

Console.WriteLine("Sockets: " + hardwareInfo.CpuList.Count);
Console.WriteLine("Total logical processors: " + hardwareInfo.CpuList.Sum(x => x.NumberOfLogicalProcessors));

results in

Sockets: 1
Total logical processors: 1

Content of /proc/cpuinfo (with two different physical id) is

processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 85
model name	: Intel(R) Xeon(R) Gold 6240R CPU @ 2.40GHz
stepping	: 7
microcode	: 0x5003302
cpu MHz		: 2399.999
cache size	: 36608 KB
physical id	: 0
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear flush_l1d arch_capabilities
bugs		: spectre_v1 spectre_v2 spec_store_bypass swapgs itlb_multihit mmio_stale_data retbleed eibrs_pbrsb
bogomips	: 4799.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 45 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 85
model name	: Intel(R) Xeon(R) Gold 6240R CPU @ 2.40GHz
stepping	: 7
microcode	: 0x5003302
cpu MHz		: 2399.999
cache size	: 36608 KB
physical id	: 2
siblings	: 1
core id		: 0
cpu cores	: 1
apicid		: 2
initial apicid	: 2
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke avx512_vnni md_clear flush_l1d arch_capabilities
bugs		: spectre_v1 spectre_v2 spec_store_bypass swapgs itlb_multihit mmio_stale_data retbleed eibrs_pbrsb
bogomips	: 4799.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 45 bits physical, 48 bits virtual
power management:

Expected behavior

CPU list should contain as many objects as there are different phycial id in /proc/cpuinfo.
The sample code should results in

Sockets: 2
Total logical processors: 2

Additional context

http://linuxhunt.blogspot.com/2010/03/understanding-proccpuinfo.html
Examples 3 and 4.

Invalid Class exception when using RefreshCPUList method

Library version

10.0.1.1

OS & OS version

Windows 10 x64 21H2 build 19044

Describe the bug

RefreshCPUList() method occurs the InvalidClass exception

To Reproduce

internal static class Program {
    static readonly IHardwareInfo HardwareInfo = new HardwareInfo();
    
    public static void Main() {
        HardwareInfo.RefreshMemoryStatus();
        HardwareInfo.RefreshCPUList(); // Exception
        
        Console.WriteLine(HardwareInfo.MemoryStatus);
        HardwareInfo.CpuList.ForEach(Console.WriteLine);
    }
}

Steps to reproduce the behavior:

  1. Open Visual Studio and create a new ConsoleApplication
  2. Add the code above
  3. Run the program

Exceptions

Unhandled exception. System.Management.ManagementException: Invalid class
at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
at Hardware.Info.Windows.HardwareInfoRetrieval.GetCpuList(Boolean includePercentProcessorTime)
at Hardware.Info.HardwareInfo.RefreshCPUList(Boolean includePercentProcessorTime)
at ConsoleApp1.Program.Main() in C:\Users\Stm07\Desktop\ConsoleApp1\Program.cs:line 10

Expected behavior

Writing CPU info to the console

How to know the machine name?

The below picture shows a comparison among the output of my app in .net framework (on the left) and the one in .net6 (on the right - it uses this open-source library of course).

image

Is there a way to get the machine name?

Cannot run in Linux, prompting the following error

Linux os:
Linux HikvisionOS 3.10.0-957.12.2.el7.x86_64 #1 SMP Mon Jul 15 17:56:54 CST 2019 x86_64 x86_64 x86_64 GNU/Linux

Error message:
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'Hardware.Info, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

File name: 'Hardware.Info, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null'
Aborted

Lack of information on Linux

Library version

100.0.0.1

OS, version, architecture (32 bit / 64 bit)

Ubuntu 64bit

Describe the bug

I have attempted to use the library on Linux to obtain information about the Bios, CPU, Drive, and Motherboard. However, I have noticed that a lot of the information is missing. I am particularly interested in obtaining the serial numbers for the Bios, Drive, and Motherboard, as well as the CPU processorId. Is it possible to retrieve this data on Linux?

To Reproduce

hardwareInfo.RefreshBIOSList();
hardwareInfo.RefreshCPUList(false);
hardwareInfo.RefreshDriveList();
hardwareInfo.RefreshMotherboardList();

foreach (var hardware in hardwareInfo.BiosList)
    Console.WriteLine(hardware);

foreach (var cpu in hardwareInfo.CpuList)
    Console.WriteLine(cpu);

foreach (var drive in hardwareInfo.DriveList)
{
    Console.WriteLine(drive);

    foreach (var partition in drive.PartitionList)
    {
        Console.WriteLine(partition);

        foreach (var volume in partition.VolumeList)
            Console.WriteLine(volume);
    }
}

foreach (var hardware in hardwareInfo.MotherboardList)
    Console.WriteLine(hardware);

Very little info seems to be collected on Debian

Library version

11.0.1

OS & OS version

Debian 11, Kernel 5.10.20

Describe the bug

We first tried on a Raspberry Pi 4, no info seems to be coming except in Networks, where IP and MAC address are one of the few pieces of information entered.

We then tried (With the same Debian distro) on a Asus h61m-f, there we get a little more information on the bios, but for instance RAM is not filled in.

For CPU on Raspberry Pi 4 it only collects the L caches for the CPU, that's it.

These attempts have been done as sudo.

We also tried running it on Windows and then it collects everything.

To Reproduce

We are just testing this for now before we decide to use it or not, as such we are just collecting everything and dumping it.

    public async Task<ClientHelperHardwareEntity> GetHardware()
    {
        var clientHelperHardwareEntity = new ClientHelperHardwareEntity();

        hardwareInfo.RefreshAll();

        var bios = hardwareInfo.BiosList.FirstOrDefault();
        if (bios != null)
        {
            clientHelperHardwareEntity.Bios = new ClientHelperHardwareBios
            {
                Caption = bios.Caption,
                Description = bios.Description,
                Manufacturer = bios.Manufacturer,
                Name = bios.Name,
                ReleaseDate = bios.ReleaseDate,
                SerialNumber = bios.SerialNumber,
                SoftwareElementID = bios.SoftwareElementID,
                Version = bios.Version,
            };
        }

        var cpu = hardwareInfo.CpuList.FirstOrDefault();
        if (cpu != null)
        {
            clientHelperHardwareEntity.Cpu = new ClientHelperHardwareCpu
            {
                Caption= cpu.Caption,
                CurrentClockSpeed = cpu.CurrentClockSpeed,
                Description = cpu.Description,
                L1InstructionCacheSize = cpu.L1InstructionCacheSize,
                L1DataCacheSize = cpu.L1DataCacheSize,
                L2CacheSize = cpu.L2CacheSize,
                L3CacheSize = cpu.L3CacheSize,
                Manufacturer = cpu.Manufacturer,
                MaxClockSpeed = cpu.MaxClockSpeed,
                Name = cpu.Name,
                NumberOfCores = cpu.NumberOfCores,
                NumberOfLogicalProcessors = cpu.NumberOfLogicalProcessors,
                ProcessorId = cpu.ProcessorId,
                SecondLevelAddressTranslationExtensions = cpu.SecondLevelAddressTranslationExtensions,
                SocketDesignation = cpu.SocketDesignation,
                VirtualizationFirmwareEnabled = cpu.VirtualizationFirmwareEnabled,
                VMMonitorModeExtensions = cpu.VMMonitorModeExtensions,
                PercentProcessorTime = cpu.PercentProcessorTime,
            };
        }

        foreach (var drive in hardwareInfo.DriveList)
        {
            clientHelperHardwareEntity.Drives.Add(new ClientHelperHardwareDrive
            {
                Caption = drive.Caption,
                Description = drive.Description,
                FirmwareRevision = drive.FirmwareRevision,
                Index = drive.Index,
                Manufacturer = drive.Manufacturer,
                Model = drive.Model,
                Name = drive.Name,
                Partitions = drive.Partitions,
                SerialNumber = drive.SerialNumber,
                Size = drive.Size,
            });
        }

        foreach (var memory in hardwareInfo.MemoryList)
        {
            clientHelperHardwareEntity.Memories.Add(new ClientHelperHardwareMemory
            {
                BankLabel = memory.BankLabel,
                Capacity = memory.Capacity,
                Manufacturer = memory.Manufacturer,
                MaxVoltage = memory.MaxVoltage,
                MinVoltage = memory.MinVoltage,
                PartNumber = memory.PartNumber,
                SerialNumber = memory.SerialNumber,
                Speed = memory.Speed,
            });
        }

        foreach (var monitor in hardwareInfo.MonitorList)
        {
            clientHelperHardwareEntity.Monitors.Add(new ClientHelperHardwareMonitor
            {
                Caption = monitor.Caption,
                Description = monitor.Description,
                MonitorManufacturer = monitor.MonitorManufacturer,
                MonitorType = monitor.MonitorType,
                Name = monitor.Name,
                PixelsPerXLogicalInch = monitor.PixelsPerXLogicalInch,
                PixelsPerYLogicalInch = monitor.PixelsPerYLogicalInch,
            });
        }

        var motherboard = hardwareInfo.MotherboardList.FirstOrDefault();
        if (motherboard != null)
        {
            clientHelperHardwareEntity.Motherboard = new ClientHelperHardwareMotherboard
            {
                Manufacturer = motherboard.Manufacturer,
                Product = motherboard.Product,
                SerialNumber = motherboard.SerialNumber,
            };
        }

        foreach (var gpu in hardwareInfo.VideoControllerList)
        {
            clientHelperHardwareEntity.Gpus.Add(new ClientHelperHardwareGpu
            {
                AdapterRAM = gpu.AdapterRAM,
                Caption = gpu.Caption,
                CurrentBitsPerPixel = gpu.CurrentBitsPerPixel,
                CurrentHorizontalResolution = gpu.CurrentHorizontalResolution,
                CurrentNumberOfColors = gpu.CurrentNumberOfColors,
                CurrentRefreshRate = gpu.CurrentRefreshRate,
                CurrentVerticalResolution = gpu.CurrentVerticalResolution,
                Description = gpu.Description,
                DriverDate = gpu.DriverDate,
                DriverVersion = gpu.DriverVersion,
                Manufacturer = gpu.Manufacturer,
                MaxRefreshRate = gpu.MaxRefreshRate,
                MinRefreshRate = gpu.MinRefreshRate,
                Name = gpu.Name,
                VideoModeDescription = gpu.VideoModeDescription,
                VideoProcessor = gpu.VideoProcessor,
            });
        }

        foreach (var network in hardwareInfo.NetworkAdapterList)
        {
            clientHelperHardwareEntity.Networks.Add(new ClientHelperHardwareNetwork
            {
                AdapterType = network.AdapterType,
                Caption = network.Caption,
                Description = network.Description,
                MACAddress = network.MACAddress,
                Manufacturer = network.Manufacturer,
                Name = network.Name,
                NetConnectionID = network.NetConnectionID,
                ProductName = network.ProductName,
                Speed = network.Speed,
                BytesSentPersec = network.BytesSentPersec,
                BytesReceivedPersec = network.BytesReceivedPersec,
                DefaultIPGatewayList = network.DefaultIPGatewayList.ConvertAll(x => new ClientHelperHardwareNetworkIp { IP = x.Address.ToString()}),
                DHCPServer = new ClientHelperHardwareNetworkIp { IP = network.DHCPServer.Address.ToString()},
                DNSServerSearchOrderList = network.DNSServerSearchOrderList.ConvertAll(x => new ClientHelperHardwareNetworkIp { IP = x.Address.ToString() }),
                IPAddressList = network.IPAddressList.Where(x => x.IsIPv6LinkLocal == false).ToList().ConvertAll(x => new ClientHelperHardwareNetworkIp { IP = x.Address.ToString() }),
                IPSubnetList = network.IPSubnetList.ConvertAll(x => new ClientHelperHardwareNetworkIp { IP = x.Address.ToString() }),
            });
        }

        foreach (var sound in hardwareInfo.SoundDeviceList)
        {
            clientHelperHardwareEntity.Sounds.Add(new ClientHelperHardwareNetworkSound
            {
                Caption = sound.Caption,
                Description = sound.Description,
                Manufacturer = sound.Manufacturer,
                Name = sound.Name,
                ProductName = sound.ProductName,
            });
        }

        _logger.LogInformation(JsonConvert.SerializeObject(clientHelperHardwareEntity, Formatting.Indented));

        return clientHelperHardwareEntity;
    }

Exceptions (if any)

No exceptions

Expected behavior

For most of the entries to be properly filled out; RAM, Cpu, Monitor,

Additional context

We are running these clients over diskless PXE, but that shouldn't be a problem should it, as it just reads the linux directories for the data it needs?

Crashes on Windows Server 2016

Library version

1.1.1.1

OS & OS version

Windows Server 2016 x64 (HyperV VM)

Describe the bug

My sample application, which is essentially a copy of your sample code from GitHub simply crashes when running on Win Server 2016.
The application is .NET 5, published as self-contained and as SingleFile:

dotnet publish -r win-x64 -v n /p:PublishSingleFile=true --sc

To Reproduce

using System;
using HardwareInformation;
using Hardware.Info;

namespace Test.HardwareInformation
{
class Program
{

    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        HardwareInformation_1();

        Console.WriteLine("Press any key to get exit...");
        Console.ReadLine();
    }
    private static void HardwareInformation_1()
    {
        try
        {
            Console.WriteLine("HardwareInformation_1: Gathering hardware info...");

            var hi = new HardwareInfo();

            hi.RefreshAll();

             Console.WriteLine("---------------------------------------------------------------------------");
            Console.WriteLine($"BatteryList:");
            foreach(var hw in hi.BatteryList)
            {
                Console.WriteLine(hw);
            }
     }
        catch (Exception ex)
        {
            Console.WriteLine($"ERROR: {ex}");
        }
    }
}

}

Exceptions (if any)

ERROR: System.PlatformNotSupportedException: The native library 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\wminet_utils.dll' does not have all required functions. Please, update the .NET Framework.
at System.Management.WmiNetUtilsHelper.<>c__DisplayClass104_0.b__39(Int32 _, IntPtr __, APTTYPE& ___)
at System.Management.MTAHelper.IsNoContextMTA()
at System.Management.MTAHelper.CreateInMTA(Type type)
at System.Management.ManagementPath.CreateWbemPath(String path)
at System.Management.ManagementPath..ctor(String path)
at System.Management.SelectQuery..ctor(String queryOrClassName)
at Hardware.Info.Windows.HardwareInfoRetrieval.GetOsVersionByWmi()
at Hardware.Info.Windows.HardwareInfoRetrieval..ctor(Nullable1 enumerationOptionsTimeout) at Hardware.Info.HardwareInfo..ctor(Boolean useAsteriskInWMI, Nullable1 timeoutInWMI)
at Test.HardwareInformation.Program.HardwareInformation_1()

Expected behavior

It should not crash, and should display the battery information.

Additional context

RefreshCPUList ThrowNoMatchException

Library version

10.1.0.1

OS & OS version

Debian GNU/Linux 11 (KVM)

Note

Command working fine on windows.

Describe the bug

hardwareInfo.RefreshCPUList(); throw ThrowNoMatchException:
"sequence contains no matching element"

at System.Linq.ThrowHelper.ThrowNoMatchException()\n
at Hardware.Info.Linux.HardwareInfoRetrieval.GetCpuUsage(CPU cpu)\n
at Hardware.Info.Linux.HardwareInfoRetrieval.GetCpuList(Boolean includePercentProcessorTime)\n

To Reproduce

  1. publish as linux-x64, release, net-core 6.0
  2. execute RefreshCPUList()

Multithread usage questions

Thank you for such great library! I have 3 questions with decreasing importance.

  1. Can this library be used in separate thread from main. I mean is can new HardwareInfo(), .RefreshAll(), and all properties be accessed from one child thread that is not main, is there is some possible caveats?
  2. Less important: Can one object HardwareInfo be used by multiple threads, is it thread safe?
  3. Even more less important: Can it be used in async context?

Create Mockable Interface for public HardwareInfo class

Is your feature request related to a problem? Please describe.
Your library isn't mockable and thus makes it difficult to unit test around.

Describe the solution you'd like
I would like an interface on the "main" HardwareInfo class that exposes the public properties and methods so that it can be mocked by a library like MOQ.

Describe alternatives you've considered
Currently, the only way to unit test methods using your library is to wrap your library in a testable interface and make your library the concrete implementation through DI. This is a less than ideal solution.

Cannot get MonitorList.

I cannot any monitor by WMI API. I've wrapped it myself and it doesn't seem to be easy to get this information. Have you ever encountered this problem?

I found it impossible to get them using the handle method. I had to use a keystroke script(such as autoit) to get the content, but it was a little less elegant.

Speccy:
image
image

[Mac] Does not retrieve CPU info for M1 chips

Library version

10.1.0

OS & OS version

macOS 13.0.1

Describe the bug

The CPU name along with some other properties like the clockspeed are empty.

To Reproduce

Run the test project on an M1 Mac.


Since I happen to have one of these (an M1 Max) I will look into submitting a fix for this. I tried manually running the command to look up the CPU and it returns the string "Apple M1 Max" but it looks like the code is assuming an @ character be present. I'll have to investigate if there are other sysctl arguments. I have an old Intel Mac mini I can set up to make sure I don't break the Intel CPU info.

Performance issue on CpuList (~30 sec refresh)

Library version
1.1.0

OS & OS version
Windows 10

Describe the bug
All results returning as expected, no errors produced, however, a couple of elements are taking excessively long to refresh.

CpuList refresh at ~30 seconds, NetworkAdapterList at ~1.1 seconds. The rest are pretty much sub 100 millisecond territory.

To Reproduce
Steps to reproduce the behavior:

  1. Execute RefreshCpuList

Expected behavior
Would be great if CpuList would return faster. If there is no way around the slowness, perhaps you could isolate the slow bits, and add options around whether to refresh them or not so that there is a fast-path available to users that don't require the extra data.

Additional context
Inspection is running on a Win 10 x64 box. Pretty standard workstation.

CPU:
{
"Caption": "Intel64 Family 6 Model 158 Stepping 9",
"CurrentClockSpeed": 4200,
"Description": "Intel64 Family 6 Model 158 Stepping 9",
"L2CacheSize": 1024,
"L3CacheSize": 8192,
"Manufacturer": "GenuineIntel",
"MaxClockSpeed": 4200,
"Name": "Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz",
"NumberOfCores": 4,
"NumberOfLogicalProcessors": 8,
"ProcessorId": "BFEBFBFF000906E9",
"VirtualizationFirmwareEnabled": true,
"VMMonitorModeExtensions": true
}

Motherboard:
{
"Manufacturer": "ASUSTeK COMPUTER INC.",
"Product": "MAXIMUS IX CODE",
}

NetworkAdapter add two properties: GUID, PNPDeviceID

GUID and PNPDeviceID can help determine the adapter is a physical device or not.
Can use informations in registery:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network{4D36E972-E325-11CE-BFC1-08002BE10318}

Linux environment broke?

Library version

1.1.1.1

OS & OS version

Arch Linux

Describe the bug

image

Only can get cpu & memory status on Linux environment.

To Reproduce

Like DriveList:

hardwareInfo.RefreshDriveList();
var disktotal = hardwareInfo.DriveList.Count; // it's 0

Exceptions (if any)

Expected behavior

Additional context

Any chance to add support for Android and iOS devices?

Any chance to add support for Android and iOS devices? I'm aware some things probably won't work, but it would be awesome if this library could support it.

Mainly looking for:
Cpu (serial number?)
Memory
Motherboard

BytesSentPersec and BytesTotalPersec of a network adapter is always 0

Library version

10.1.1.1

OS & OS version

Windows 10 and 11, could also be on other windows version, too. But I have only Windows 11 on my machine.

Describe the bug

BytesSentPersec and BytesTotalPersec of a network adapter is always 0, no matter how many data are sent or received.

To Reproduce

The problem here is that the network adapter name from "SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter=True AND MACAddress IS NOT NULL" is with a #. See screenshot:
win32_networkadapter
But if you try to read the BytesSentPerSec and BytesTotalPersec, the network name to match has changed with a _
See screenshot:
Win32_PerfFormattedData_Tcpip_NetworkAdapter

In the class HardwareInfoRetrieval.cs:564 you are already change ( with [ and ) with ], so I think you will also need to change a # to _ if they appear in the name otherwise it won't match and the values will always be 0

Expected behavior

BytesSentPersec and BytesTotalPersec should show the correct value

Drive info not available in Linux

100.0.1.1

Raspberry OS 5/6, ubuntu 22

Describe the bug

Driver info doesn't work on linux, but it does on windows

To Reproduce

Program.cs

namespace nunaSysMon
{
  public class Program
  {
    public static void Main(string[] args)
    {
      var builder = Host.CreateApplicationBuilder(args);
      builder.Services.AddHostedService<Worker>();

      var host = builder.Build();
      host.Run();
    }
  }
}

worker.cs

using Hardware.Info;

namespace nunaSysMon
{
  public class Worker : BackgroundService
  {
    private readonly ILogger<Worker> _logger;
    private readonly IHardwareInfo _hardwareInfo = new HardwareInfo();
    
    public Worker(ILogger<Worker> logger)
    {
      _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
      ulong _cpuTime = 0;
      _hardwareInfo.RefreshAll();
      Console.WriteLine("------------------------------------>>");
      Console.WriteLine($"Delay 21s");
      Console.WriteLine("------------------------------------>>");
      await Task.Delay(21000, stoppingToken);
      while (!stoppingToken.IsCancellationRequested)
      {
        if (_logger.IsEnabled(LogLevel.Information))
        {
          _cpuTime = 0;
          _hardwareInfo.RefreshCPUList();
          _hardwareInfo.CpuList.ForEach(a => _cpuTime += a.PercentProcessorTime);
          _hardwareInfo.RefreshMemoryStatus();
          var _fMemmory = (_hardwareInfo.MemoryStatus.AvailablePhysical / (1024 * 1024 * 1024));
          var _tMemmory = (_hardwareInfo.MemoryStatus.TotalPhysical / (1024 * 1024 * 1024));
          var _fpMemory = _fMemmory * 100 / _tMemmory;
          Console.WriteLine("------------------------------------>>");
          Console.WriteLine($"SO: {_hardwareInfo.OperatingSystem}");
          
          Console.WriteLine($"CPU %: {_cpuTime}");
          Console.WriteLine($"Mem Free: {_fMemmory.ToString("#,##0.##")}Gb / {_fpMemory}%");
          
          _hardwareInfo.RefreshDriveList();          
          Console.WriteLine($"Drives:");
          
          foreach (var drive in _hardwareInfo.DriveList)
          {
            foreach (var partition in drive.PartitionList)
            {
              foreach (Volume v in partition.VolumeList)
              {
                var _pSpace = v.FreeSpace * 100 / v.Size;
                var _fSpace = v.FreeSpace / (1024 * 1024 * 1024);
                Console.WriteLine($"\t{v.Name} {_fSpace}Gb / {_pSpace}%");
              }
            }
          }
        }
        await Task.Delay(15000, stoppingToken);
      }
    }
  }
}

Steps to reproduce the behavior:

  1. Open Visual Studio and create a new project using this template '...'
  2. Add this code '...' in this class '...' to this method '...' in this line '...'
  3. Run the program

If you don't provide C# code to reproduce the problem, the issue will be closed.

Exceptions (if any)

Expected behavior

Additional context

Not all Monitors/Screens returned on Windows

Library version

11.1.0.1

OS & OS version

OS Name: Microsoft Windows 11 Home
OS Version: 10.0.22621 N/A Build 22621

Describe the bug

I got three screens connected, but only one is returned when querying hardwareInfo.MonitorList

To Reproduce

using Hardware.Info;

var hardwareInfo = new HardwareInfo(useAsteriskInWMI: true);
hardwareInfo.RefreshAll();

foreach (var hardware in hardwareInfo.MonitorList)
    Console.WriteLine(hardware);

Steps to reproduce the behavior:

  1. Open Visual Studio and create a command line application targeting .net6
  2. Install the package
  3. Have at least two monitors connected
  4. Paste above code snippet to Program.cs
  5. Run the program

Exceptions (if any)

Expected behavior

All monitors should be shown.

Additional context

I found this https://stackoverflow.com/a/36788720/1199089 stack overflow post that suggests there are two possible origins for dieplays. If I use the second origin on my machine, I get all screens connected.

Question: Obtaining CPU Utilization Metrics

First off, big thanks for this awesome lib! I'm digging into CPU metrics on Windows and wondering how to get the PercentProcessorUtility instead of PercentProcessorTime. It seems more in line with Task Manager's display. Any tips on grabbing this specific metric?

Windows support without WMI

Is your feature request related to a problem? Please describe.
I have experience numerous machine where WMI is corrupted resulting in a ManagementException
WMI is also really slow, so wanting

Describe the solution you'd like
Since WMI is Windows specific anyways, wouldn't it be possible to get more or less the same values using Win32 APIs.
I imagine this being faster and not prone to corrupted WMI.

Describe alternatives you've considered
Much of the information could be retrieved through Win32 API:
https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info
Windows version (name) is available in the branding api
https://dennisbabkin.com/blog/?t=how-to-tell-the-real-version-of-windows-your-app-is-running-on#ver_string

VideoController.AdapterRAM does not report > 4GB

Library version

11.0.0.1

OS & OS version

Windows 11 22H2 (but the bug is on ALL versions of Windows)

Describe the bug

VideoController.AdapterRAM is a 32 bit unsigned int and therefore limited to represent 4GB. The Windows code fills the value using WMI which unfortunately has the same bug. Any video controller with more than 4GB will be reported as having 4GB by WMI
(see https://www.google.com/search?q=wmi+adapterram+4gb)

To Reproduce

On a windows machine with a video controller with more than 4GB dedicated memory

var info = new HardwareInfo();
info.RefreshVideoControllerList();
var ram = info.VideoControllers[0].AdapterRAM;

Expected behavior

Actual amount of memory should be reported

GPU Usage Infomation

I want to to get GPU usage to monitor GPU informaton, but it seems that I cannot find API here. ๐Ÿค”
Thank you for many functions you provide in this package, it really helps me a lot. โค๏ธ

About the timeout exception.

Hi, i'm sorry for this issue report and it's actually not a bug nor feature request....
just i'm confused about the WMI timeout value.
if i initialize the class this way:

var hardwareInfo = new HardwareInfo(false, TimeSpan.FromSeconds(1));

it will work normally even if fianlly it takes 6seconds.
but if i initialize it with TimeSpan.FromTicks(1) it will fail to create HardwareInfo instance.
(if pass null for the TimeSpan argument it will also throw exception immediately, for this case i can understand it's an invalid argument or something like that)
anyway, why 1 second works and 1 tick not?
what is the proper shortest timeout to choose?
thanks so much!
or maybe we can make the instance creating alwasy success, but fail on RefeshXXX methods?

Expose method to get the Windows OS version

Is your feature request related to a problem? Please describe.
Retrieve the Windows OS version

Describe the solution you'd like
Want to retrieve the Windows OS version.

Describe alternatives you've considered
Currently using ManagementObjectSearcher to get the OS version used

using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem"))
{
      foreach (ManagementObject os in searcher.Get())
      {
         OSCaption = os["Caption"].ToString();
         break;
      }
}

Additional context
I have seen methods being called to get the windows OS version here. Is it possible to expose this so we can use this in our application to detect the windows version.

Not work in console app

Library version

11.0.0.1

OS & OS version

Windows 11

Describe the bug

RefreshAll() method throw System.Management currently is only supported for Windows desktop applications.

To Reproduce

IHardwareInfo hardwareInfo = new HardwareInfo();
hardwareInfo.RefreshAll();

Dotnet runtime

.net core 3.1

CurrentClockSpeed isn't correctly calculated on Windows.

Library version

10.1.1

OS & OS version

Windows 11, latest as of 2023-03-11

Describe the bug

cpu.CurrentClockSpeed is incorrect on some processors. Those processors scale performance based on load. Under high load it is lower than the actual clock speed. Under light load it is higher than the actual clock speed. In fact it always the same as cpu.MaxClockSpeed.

Context

Modern CPUs can scale their performance. The code for this library only uses WMI queries. WMI does not appear to account for this fact.

The correct calculation for those sorts of CPUs is to scale the maximum CPU speed returned by the current WMI query being done by the Windows Performance Counter: \Processor Information(_Total)% Processor Performance

This SO question has the correct calculation in the answer.

To Reproduce

Physical Environment.

  1. Use a computer with a processor that scales its performance based on load. This is a critical element in reproducing this issue.
  2. Run Windows 11. (More likely than not Win8+ will be fine)

Example processor: 12th Gen Intel(R) Core(TM) i7-12700H

Steps

  1. Place your CPU under heavy load.
  2. Go to Device Manager and observe your CPU speed. (In my case it reads roughly 3.4-3.5GHz)
  3. Run HardwareInfo.RefreshCPUList() while under heavy load.

Expected Result

When my CPU, which is 2.3Ghz, is at 150% ProcessorPerformance I should get 3450 for cpu.CurrentClockSpeed.

Actual Result

cpu.CurrentClockSpeed reads 2300.

As for this: If you don't provide C# code to reproduce the problem, the issue will be closed.
Since this is hardware specific, and I've pinpointed the root cause, the correct calculation, and an StackOverflow article with code you should be able to all but copy and paste from, you should have all the information you need to proceed, for Windows. Hardware may be a different story. I don't know about Macs or Linux.
So, please make an exception. You will need to get the right hardware... or someone with it willing to run the code and report findings... I'm willing to be that guinea pig.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

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

  • D3 photo D3

    Data-Driven Documents codes.