Jinjinov / Hardware.Info

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.
MIT License
480 stars 77 forks source link

Lack of information on Linux #57

Closed simonedd closed 9 months ago

simonedd commented 9 months ago

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);
Jinjinov commented 9 months ago

Thank you for reaching out!

Please list exactly which properties you are interested in, like so:

and show me the output from your PC, as I can't know which properties you get and which you don't get (this can be different on each computer, because of the hardware and firmware)

simonedd commented 9 months ago

These are the properties I'm interested in:

This is the output on my PC:

// BIOS
Caption: 
Description: 
Manufacturer: Insyde
Name: 
ReleaseDate: 11/12/2013
SerialNumber: 
SoftwareElementID: 
Version: F.2A

// CPU
Caption: 
CurrentClockSpeed: 3093789
Description: 
L1InstructionCacheSize: 32768
L1DataCacheSize: 32768
L2CacheSize: 262144
L3CacheSize: 6291456
Manufacturer: GenuineIntel
MaxClockSpeed: 0
Name: Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz
NumberOfCores: 4
NumberOfLogicalProcessors: 8
PercentProcessorTime: 0
ProcessorId: 0
SecondLevelAddressTranslationExtensions: False
SocketDesignation: 
VirtualizationFirmwareEnabled: False
VMMonitorModeExtensions: False

// DRIVE
Caption: 
Description: 
FirmwareRevision: 
Index: 0
Manufacturer: 
Model: 
Name: 
Partitions: 0
SerialNumber: 
Size: 0

// MOTHERBOARD
Manufacturer: Hewlett-Packard
Product: 181B
SerialNumber: 
Jinjinov commented 9 months ago

Thank you, I will look into it

Jinjinov commented 9 months ago

The value of CPU.ProcessorId is correct - in Linux this is just the index of the processor. If you have a PC with 4 processors, their ID will be 0, 1, 2, 3 in Linux. Read more here: https://linuxhunt.blogspot.com/2010/03/understanding-proccpuinfo.html

The value for Motherboard.SerialNumber is already retrieved from /sys/class/dmi/id/board_serial. If your value is an empty string, that means that your Ubuntu couldn't find a value for /sys/class/dmi/id/board_serial.

I don't know why exactly Microsoft decided to add SerialNumber to the Win32_BIOS class - see: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-bios - but I included it anyway in Hardware.Info. A bios serial number doesn't make much sense, what you want is BIOS.Version which is already read in Linux from /sys/class/dmi/id/bios_version

I might be able to get Drive.SerialNumber from /sys/class/block/ or /dev/disk/by-id/ - I will take a look.

simonedd commented 9 months ago

Thanks for your response. I'm trying to create a unique identifier for a machine, but the BIOS.Version could be the same on different PCs. Are you aware of the best properties to create a unique ID for a machine?

Jinjinov commented 9 months ago

If you want to cover 99% of cases, just use the MAC address.

If you want to cover 100% of cases, this problem becomes very hard.

If you are in control of the PC where you want to get the unique machine id, you can use and/or install some Linux tools and run them with sudo, such as: dmidecode, lshw, see here: https://www.baeldung.com/linux/machine-id

simonedd commented 9 months ago

Thanks for the suggestions. Please let me know if you can add the Drive.SerialNumber as well.

Jinjinov commented 9 months ago

If this is very important to you and you don't want to just use the MAC address, you can create a C++ dll with the assembly code, like here: https://stackoverflow.com/questions/6491566/getting-the-machine-serial-number-and-cpu-id-using-c-c-in-linux and then use https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke with either https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute?view=net-8.0 or the new https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.libraryimportattribute?view=net-8.0 to call the C++ methods from your C# code.

For the CPU, getting a serial is only possible on Pentium III: https://en.wikipedia.org/wiki/CPUID#EAX=3:_Processor_Serial_Number https://en.wikipedia.org/wiki/Pentium_III#Controversy_about_privacy_issues

I will add Drive.SerialNumber when I have the time.

Jinjinov commented 9 months ago

Added Drive.SerialNumber in: https://github.com/Jinjinov/Hardware.Info/releases/tag/v100.0.1.0