From ca615c952fe432e6b77824bcdd80c2c2abb492d7 Mon Sep 17 00:00:00 2001 From: Florian Porsch Date: Mon, 7 Feb 2022 17:18:16 +0100 Subject: [PATCH] Fix crash of LibreHardwareMonitorLib using Linux and Net5 / Add RAM support for linux (#573) Thanks to @Tederean. --- LibreHardwareMonitorLib/Hardware/InpOut.cs | 3 + .../Hardware/Memory/GenericLinuxMemory.cs | 96 +++++++++++++++++++ ...nericMemory.cs => GenericWindowsMemory.cs} | 4 +- .../Hardware/Memory/MemoryGroup.cs | 9 +- LibreHardwareMonitorLib/Hardware/OpCode.cs | 10 ++ .../LibreHardwareMonitorLib.csproj | 4 +- 6 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 LibreHardwareMonitorLib/Hardware/Memory/GenericLinuxMemory.cs rename LibreHardwareMonitorLib/Hardware/Memory/{GenericMemory.cs => GenericWindowsMemory.cs} (94%) diff --git a/LibreHardwareMonitorLib/Hardware/InpOut.cs b/LibreHardwareMonitorLib/Hardware/InpOut.cs index 3c6ae50..cf84958 100644 --- a/LibreHardwareMonitorLib/Hardware/InpOut.cs +++ b/LibreHardwareMonitorLib/Hardware/InpOut.cs @@ -19,6 +19,9 @@ namespace LibreHardwareMonitor.Hardware public static bool Open() { + if (Software.OperatingSystem.IsUnix) + return false; + if (IsOpen) return true; diff --git a/LibreHardwareMonitorLib/Hardware/Memory/GenericLinuxMemory.cs b/LibreHardwareMonitorLib/Hardware/Memory/GenericLinuxMemory.cs new file mode 100644 index 0000000..2e196cd --- /dev/null +++ b/LibreHardwareMonitorLib/Hardware/Memory/GenericLinuxMemory.cs @@ -0,0 +1,96 @@ +// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// Copyright (C) LibreHardwareMonitor and Contributors. +// Partial Copyright (C) Michael Möller and Contributors. +// All Rights Reserved. + +using System.IO; +using System.Linq; + +namespace LibreHardwareMonitor.Hardware.Memory +{ + internal sealed class GenericLinuxMemory : Hardware + { + private readonly Sensor _physicalMemoryAvailable; + private readonly Sensor _physicalMemoryLoad; + private readonly Sensor _physicalMemoryUsed; + private readonly Sensor _virtualMemoryAvailable; + private readonly Sensor _virtualMemoryLoad; + private readonly Sensor _virtualMemoryUsed; + + + public override HardwareType HardwareType => HardwareType.Memory; + + + public GenericLinuxMemory(string name, ISettings settings) : base(name, new Identifier("ram"), settings) + { + _physicalMemoryUsed = new Sensor("Memory Used", 0, SensorType.Data, this, settings); + ActivateSensor(_physicalMemoryUsed); + + _physicalMemoryAvailable = new Sensor("Memory Available", 1, SensorType.Data, this, settings); + ActivateSensor(_physicalMemoryAvailable); + + _physicalMemoryLoad = new Sensor("Memory", 0, SensorType.Load, this, settings); + ActivateSensor(_physicalMemoryLoad); + + _virtualMemoryUsed = new Sensor("Virtual Memory Used", 2, SensorType.Data, this, settings); + ActivateSensor(_virtualMemoryUsed); + + _virtualMemoryAvailable = new Sensor("Virtual Memory Available", 3, SensorType.Data, this, settings); + ActivateSensor(_virtualMemoryAvailable); + + _virtualMemoryLoad = new Sensor("Virtual Memory", 1, SensorType.Load, this, settings); + ActivateSensor(_virtualMemoryLoad); + } + + + public override void Update() + { + try + { + var memoryInfo = File.ReadAllLines("/proc/meminfo"); + + { + var totalMemory_GB = GetMemInfoValue(memoryInfo.First(entry => entry.StartsWith("MemTotal:"))) / 1024.0f / 1024.0f; + var freeMemory_GB = GetMemInfoValue(memoryInfo.First(entry => entry.StartsWith("MemFree:"))) / 1024.0f / 1024.0f; + var cachedMemory_GB = GetMemInfoValue(memoryInfo.First(entry => entry.StartsWith("Cached:"))) / 1024.0f / 1024.0f; + + var usedMemory_GB = totalMemory_GB - freeMemory_GB - cachedMemory_GB; + + _physicalMemoryUsed.Value = usedMemory_GB; + _physicalMemoryAvailable.Value = totalMemory_GB; + _physicalMemoryLoad.Value = 100.0f * (usedMemory_GB / totalMemory_GB); + } + { + var totalSwapMemory_GB = GetMemInfoValue(memoryInfo.First(entry => entry.StartsWith("SwapTotal"))) / 1024.0f / 1024.0f; + var freeSwapMemory_GB = GetMemInfoValue(memoryInfo.First(entry => entry.StartsWith("SwapFree"))) / 1024.0f / 1024.0f; + var usedSwapMemory_GB = totalSwapMemory_GB - freeSwapMemory_GB; + + _virtualMemoryUsed.Value = usedSwapMemory_GB; + _virtualMemoryAvailable.Value = totalSwapMemory_GB; + _virtualMemoryLoad.Value = 100.0f * (usedSwapMemory_GB / totalSwapMemory_GB); + } + } + catch + { + _physicalMemoryUsed.Value = null; + _physicalMemoryAvailable.Value = null; + _physicalMemoryLoad.Value = null; + + _virtualMemoryUsed.Value = null; + _virtualMemoryAvailable.Value = null; + _virtualMemoryLoad.Value = null; + } + } + + private long GetMemInfoValue(string line) + { + // Example: "MemTotal: 32849676 kB" + + var valueWithUnit = line.Split(':').Skip(1).First().Trim(); + var valueAsString = valueWithUnit.Split(' ').First(); + + return long.Parse(valueAsString); + } + } +} diff --git a/LibreHardwareMonitorLib/Hardware/Memory/GenericMemory.cs b/LibreHardwareMonitorLib/Hardware/Memory/GenericWindowsMemory.cs similarity index 94% rename from LibreHardwareMonitorLib/Hardware/Memory/GenericMemory.cs rename to LibreHardwareMonitorLib/Hardware/Memory/GenericWindowsMemory.cs index 42063ec..0e45b15 100644 --- a/LibreHardwareMonitorLib/Hardware/Memory/GenericMemory.cs +++ b/LibreHardwareMonitorLib/Hardware/Memory/GenericWindowsMemory.cs @@ -9,7 +9,7 @@ using LibreHardwareMonitor.Interop; namespace LibreHardwareMonitor.Hardware.Memory { - internal sealed class GenericMemory : Hardware + internal sealed class GenericWindowsMemory : Hardware { private readonly Sensor _physicalMemoryAvailable; private readonly Sensor _physicalMemoryLoad; @@ -18,7 +18,7 @@ namespace LibreHardwareMonitor.Hardware.Memory private readonly Sensor _virtualMemoryLoad; private readonly Sensor _virtualMemoryUsed; - public GenericMemory(string name, ISettings settings) : base(name, new Identifier("ram"), settings) + public GenericWindowsMemory(string name, ISettings settings) : base(name, new Identifier("ram"), settings) { _physicalMemoryUsed = new Sensor("Memory Used", 0, SensorType.Data, this, settings); ActivateSensor(_physicalMemoryUsed); diff --git a/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs b/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs index 271893b..9df7da3 100644 --- a/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs +++ b/LibreHardwareMonitorLib/Hardware/Memory/MemoryGroup.cs @@ -14,13 +14,14 @@ namespace LibreHardwareMonitor.Hardware.Memory public MemoryGroup(ISettings settings) { - // No implementation for RAM on Unix systems if (Software.OperatingSystem.IsUnix) { - _hardware = new Hardware[0]; - return; + _hardware = new Hardware[] { new GenericLinuxMemory("Generic Memory", settings) }; + } + else + { + _hardware = new Hardware[] { new GenericWindowsMemory("Generic Memory", settings) }; } - _hardware = new Hardware[] { new GenericMemory("Generic Memory", settings) }; } public string GetReport() diff --git a/LibreHardwareMonitorLib/Hardware/OpCode.cs b/LibreHardwareMonitorLib/Hardware/OpCode.cs index e97fe60..51659e2 100644 --- a/LibreHardwareMonitorLib/Hardware/OpCode.cs +++ b/LibreHardwareMonitorLib/Hardware/OpCode.cs @@ -225,7 +225,12 @@ namespace LibreHardwareMonitor.Hardware if (Software.OperatingSystem.IsUnix) { +#if NETFRAMEWORK Assembly assembly = Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, " + "PublicKeyToken=0738eb9f132ed756"); +#else + Assembly assembly = Assembly.Load("Mono.Posix.NETStandard, Version=1.0.0.0, Culture=neutral"); +#endif + Type sysCall = assembly.GetType("Mono.Unix.Native.Syscall"); MethodInfo mmap = sysCall.GetMethod("mmap"); @@ -265,7 +270,12 @@ namespace LibreHardwareMonitor.Hardware if (Software.OperatingSystem.IsUnix) { +#if NETFRAMEWORK Assembly assembly = Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, " + "PublicKeyToken=0738eb9f132ed756"); +#else + Assembly assembly = Assembly.Load("Mono.Posix.NETStandard, Version=1.0.0.0, Culture=neutral"); +#endif + Type sysCall = assembly.GetType("Mono.Unix.Native.Syscall"); MethodInfo method = sysCall.GetMethod("munmap"); method?.Invoke(null, new object[] { _codeBuffer, _size }); diff --git a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj index 2b2f9de..48b71e9 100644 --- a/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj +++ b/LibreHardwareMonitorLib/LibreHardwareMonitorLib.csproj @@ -37,12 +37,14 @@ + + @@ -54,4 +56,4 @@ - \ No newline at end of file +