C# - 整合LibreHardwareMonitor库实现硬件监控教程(温度、CPU、内存、网络、硬盘、风扇等)
作者:hangge | 2024-12-24 08:50
我前面写过文章演示如何使用 C++ 编写一个电脑硬件监控程序(点击查看),借助 LibreHardwareMonitor 这个第三方库(GitHub 主页),实时获取计算机的 CPU 利用率、内存利用率、显卡利用率、CPU 温度、显卡温度、硬盘温度、主板温度、硬盘利用率、CPU 频率、风扇转速、总网速、实时上传速率、实时下载速率等一系列监控指标。本文接着演示如何使用 C# 实现同样的功能。
![](http://hangge.com/blog_uploads/202412/2024122017193948004.png)
![](http://hangge.com/blog_uploads/202412/2024122211170457627.png)
![](http://hangge.com/blog_uploads/202412/2024122211174296659.png)
![](http://hangge.com/blog_uploads/202412/2024122021155226088.png)
![](http://hangge.com/blog_uploads/202412/2024122021300165827.png)
![](http://hangge.com/blog_uploads/202412/2024122117445850415.png)
(2)程序入口类 Program.cs 代码如下:
1,创建项目
(1)使用“以管理员身份运行”方式打开 Visual Studio。如果没有管理员权限,程序运行调试时温度监控、显卡利用率、硬盘利用率、风扇转速等硬件监控信息会获取不到。
![](http://hangge.com/blog_uploads/202412/2024122017193948004.png)
(2)为方便演示,我这里创建一个“控制台应用”
![](http://hangge.com/blog_uploads/202412/2024122211163154509.png)
(3)项目创建完毕后,在解决方案资源管理器中右键点击项目名称,选择 Manage NuGet Packages...(管理 NuGet 程序包...)。
![](http://hangge.com/blog_uploads/202412/2024122211170457627.png)
(4)在 NuGet 窗口中,切换到 Browse(浏览) 选项卡。搜索 LibreHardwareMonitor,然后安装对应的包。
![](http://hangge.com/blog_uploads/202412/2024122211174296659.png)
2,编写代码
我们将项目默认生成的 Program.cs 文件内容修改成如下代码。该代码通过调用 LibreHardwareMonitorLib 实现对计算机硬件信息(如 CPU、GPU、内存等)的实时监控和递归输出,每隔 5 秒更新一次。
using System; using System.Threading; using LibreHardwareMonitor.Hardware; class Program { // 函数:GetHardwareInfo // 描述:递归获取硬件信息并打印到控制台 // 参数:IHardware hardware - 当前硬件对象 // 返回值:void static void GetHardwareInfo(IHardware hardware) { try { hardware.Update(); // 更新硬件数据 // 根据硬件类型执行不同的操作 switch (hardware.HardwareType) { case HardwareType.Cpu: Console.WriteLine("CPU Information:"); break; case HardwareType.GpuIntel: case HardwareType.GpuNvidia: case HardwareType.GpuAmd: Console.WriteLine("GPU Information:"); break; case HardwareType.Memory: Console.WriteLine("Memory Information:"); break; case HardwareType.Motherboard: Console.WriteLine("Motherboard Information:"); break; case HardwareType.Storage: Console.WriteLine("Storage Information:"); break; case HardwareType.Network: Console.WriteLine("Network Information:"); break; case HardwareType.SuperIO: Console.WriteLine("SuperIO Information:"); break; default: Console.WriteLine("Unknown Hardware Type."); break; } // 遍历所有传感器,获取并打印传感器名称和值 foreach (var sensor in hardware.Sensors) { string name = sensor.Name; float? value = sensor.Value; if (value.HasValue) { Console.WriteLine($" {name}: {value.Value}"); } } // 递归处理子硬件信息 foreach (var subHardware in hardware.SubHardware) { GetHardwareInfo(subHardware); } } catch (Exception ex) { // 捕获并打印异常信息 Console.WriteLine($"Error: {ex.Message}"); } } static void Main() { // 创建 Computer 对象,用于管理硬件信息 Computer computer = new Computer { IsCpuEnabled = true, IsGpuEnabled = true, IsMemoryEnabled = true, IsMotherboardEnabled = true, IsControllerEnabled = true, IsNetworkEnabled = true, IsStorageEnabled = true, IsBatteryEnabled = true }; computer.Open(); // 打开硬件监控 while (true) { // 遍历所有硬件并获取信息 foreach (var hardware in computer.Hardware) { GetHardwareInfo(hardware); } // 延迟 5 秒后继续监控 Thread.Sleep(5000); } } }
3,运行测试
(1)我们可以点击 Visual Studio 顶部工具栏的运行、或者调试按钮启动程序。
![](http://hangge.com/blog_uploads/202412/2024122021093781247.png)
- 也可以直接运行生成的 exe(注意右键选择“以管理员身份运行”)
![](http://hangge.com/blog_uploads/202412/2024122021155226088.png)
(2)程序启动后控制台输出内容如下:
![](http://hangge.com/blog_uploads/202412/2024122021300165827.png)
附:功能优化改进
1,改进说明
(1)上面样例只是简单地把所有通过 LibreHardwareMonitor 库获取到所有硬件信息直接打印出来,不是很直观。这里我对代码进行如下改进:
- 创建一个专门的 HardwareMonitor 工具类实现各类监控数据的分析和保存,方便后续使用。
- 由于可能存在多块硬盘。因此除了保存所有硬盘的温度、使用率外,还存储了所有硬盘中目前最高的温度和使用率。
- 由于可能存在多个风扇。因此除了保存所有风扇的转速外,还存储了所有风扇中目前最高转速。
- 网络上下行速率根据数值的大小,动态选择合适的单位显示(KB/s、MB/s、GB/s、TB/s)
(2)程序执行效果如下:
![](http://hangge.com/blog_uploads/202412/2024122117445850415.png)
2,完整代码
(1)监控工具类 HardwareMonitor.cs 代码如下:
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using LibreHardwareMonitor.Hardware; public class HardwareMonitor { // 私有静态变量,用于存储单例实例 private static HardwareMonitor _instance; // 锁对象,用于线程安全 private static readonly object _lock = new object(); // 私有构造函数,防止外部实例化 private HardwareMonitor() { // 创建 Computer 对象,用于管理硬件信息 computer = new Computer { IsCpuEnabled = true, IsGpuEnabled = true, IsMemoryEnabled = true, IsMotherboardEnabled = true, IsControllerEnabled = true, IsNetworkEnabled = true, IsStorageEnabled = true, IsBatteryEnabled = true }; } // 公共静态方法,返回唯一的实例 public static HardwareMonitor Instance { get { // 确保线程安全 lock (_lock) { if (_instance == null) { _instance = new HardwareMonitor(); } return _instance; } } } private Computer computer; // Computer 对象,用于管理硬件信息 public Computer GetComputer() { return computer; } private float m_cpu_usage = -1; // CPU利用率 private float m_cpu_freq = -1; // CPU频率 private float m_cpu_temperature = -1; // CPU温度 private float m_memory_usage = -1; // 内存利用率 private float m_gpu_temperature = -1; // GPU温度 private float m_hdd_temperature = -1; // 硬盘温度(所有硬盘中最高温度) private float m_hdd_usage = -1; // 硬盘利用率(所有硬盘中占用率最高的) private float m_main_board_temperature = -1; // 主板温度 private float m_gpu_usage = -1; // GPU利用率 private float m_fan_speed = -1; // 风扇转速(所有风扇中转速最大一个) private float m_out_speed = -1; // 上传速率 private float m_in_speed = -1; // 下载速率 private Dictionary<string, float> m_all_hdd_temperature = new(); // 所有硬盘温度 private Dictionary<string, float> m_all_cpu_temperature = new(); // 所有 CPU 核心温度 private Dictionary<string, float> m_all_cpu_clock = new(); // 所有 CPU 核心频率 private Dictionary<string, float> m_all_hdd_usage = new(); // 所有硬盘利用率 private Dictionary<string, float> m_all_fan_speed = new(); // 所有风扇转速 // 重置所有值 public void ResetAllValues() { m_cpu_usage = -1; m_cpu_freq = -1; m_cpu_temperature = -1; m_memory_usage = -1; m_gpu_temperature = -1; m_hdd_temperature = -1; m_main_board_temperature = -1; m_gpu_usage = -1; m_hdd_usage = -1; m_fan_speed = -1; m_out_speed = -1; m_in_speed = -1; m_all_hdd_temperature.Clear(); m_all_hdd_usage.Clear(); m_all_fan_speed.Clear(); } // 数据大小格式化显示 public string DataSizeToString(float size, bool withSpace) { string formattedSize; if (size < 1024 * 10) formattedSize = $"{size / 1024.0f:F2} KB"; else if (size < 1024 * 1024) formattedSize = $"{size / 1024.0f:F1} KB"; else if (size < 1024 * 1024 * 1024) formattedSize = $"{size / 1024.0f / 1024.0f:F2} MB"; else if (size < 1024L * 1024 * 1024 * 1024) formattedSize = $"{size / 1024.0f / 1024.0f / 1024.0f:F2} GB"; else formattedSize = $"{size / 1024.0f / 1024.0f / 1024.0f / 1024.0f:F2} TB"; return withSpace ? formattedSize : formattedSize.Replace(" ", ""); } // 输出所有值 public void PrintAllValues() { DateTime now = DateTime.Now; Console.WriteLine($"------ {now:HH:mm:ss} ------"); Console.WriteLine($"CPU负载: {m_cpu_usage} %"); Console.WriteLine($"CPU频率: {m_cpu_freq} GHz"); Console.WriteLine($"CPU温度: {m_cpu_temperature} ℃"); Console.WriteLine($"内存负载: {m_memory_usage} %"); Console.WriteLine($"GPU温度: {m_gpu_temperature} ℃"); Console.WriteLine($"GPU负载: {m_gpu_usage} %"); Console.WriteLine($"主板温度: {m_main_board_temperature} ℃"); Console.WriteLine($"硬盘最高温度: {m_hdd_temperature} ℃"); foreach (var pair in m_all_hdd_temperature) Console.WriteLine($" 硬盘【{pair.Key}】温度: {pair.Value} ℃"); Console.WriteLine($"硬盘最高使用率: {m_hdd_usage} %"); foreach (var pair in m_all_hdd_usage) Console.WriteLine($" 硬盘【{pair.Key}】使用率: {pair.Value} %"); Console.WriteLine($"风扇最大转速: {m_fan_speed} 转/分"); foreach (var pair in m_all_fan_speed) Console.WriteLine($" 风扇【{pair.Key}】转速: {pair.Value} 转/分"); Console.WriteLine($"上传速率: {DataSizeToString(m_out_speed, true)}/s"); Console.WriteLine($"下载速率: {DataSizeToString(m_in_speed, true)}/s"); Console.WriteLine(); } // 将值插入到字典中,如果键已存在,则在末尾添加" #1",如果已经存在" #1",则将其加1 public void InsertValueToDictionary(Dictionary<string, float> valueMap, string key, float value) { if (valueMap.ContainsKey(key)) { string existingKey = key; int index = existingKey.LastIndexOf('#'); if (index != -1 && int.TryParse(existingKey[(index + 1)..], out int num)) { existingKey = existingKey[..index] + $"#{++num}"; } else { existingKey += " #1"; } valueMap[existingKey] = value; } else { valueMap[key] = value; } } // 将 C# 的 String 类型转换为 C# 的标准 wstring 类型 public string ClrStringToStdWstring(string str) { return str ?? string.Empty; } // 计算 CPU 利用率 public bool GetCpuUsage(IHardware hardware, ref float cpuUsage) { foreach (var sensor in hardware.Sensors) { // 找到负载传感器 if (sensor.SensorType == SensorType.Load) { // 检查传感器名称是否为 "CPU Total" if (sensor.Name == "CPU Total") { cpuUsage = (float)(sensor.Value ?? -1); return true; } } } return false; } // 计算 CPU 温度(所有核心温度的平均值) public bool GetCpuTemperature(IHardware hardware, ref float temperature) { var allCpuTemperatures = new Dictionary<string, float>(); foreach (var sensor in hardware.Sensors) { // 找到温度传感器 if (sensor.SensorType == SensorType.Temperature) { string name = sensor.Name; // 保存每个 CPU 传感器的温度 if (sensor.Value.HasValue) { allCpuTemperatures[ClrStringToStdWstring(name)] = (float)sensor.Value.Value; } } } // 计算平均温度 if (allCpuTemperatures.Count > 0) { float sum = 0; foreach (var temp in allCpuTemperatures.Values) { sum += temp; } temperature = sum / allCpuTemperatures.Count; } return temperature > 0; } // 计算 CPU 频率(所有核心时钟频率的平均值) public bool GetCPUFreq(IHardware hardware, ref float freq) { freq = 0; m_all_cpu_clock.Clear(); foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Clock) { string name = sensor.Name; if (name != "Bus Speed") { if (sensor.Value.HasValue) { m_all_cpu_clock[name] = (float)sensor.Value; } } } } if (m_all_cpu_clock.Count > 0) { float sum = 0; foreach (var clock in m_all_cpu_clock.Values) { sum += clock; } freq = sum / m_all_cpu_clock.Count / 1000.0f; // 转换为 GHz } return true; } // 计算内存利用率 public bool GetMemoryUsage(IHardware hardware, ref float memoryUsage) { foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Load && sensor.Name == "Memory") { if (sensor.Value.HasValue) { memoryUsage = (float)sensor.Value; return true; } } } return false; } // 计算硬件温度(GPU、主板、硬盘) public bool GetHardwareTemperature(IHardware hardware, ref float temperature) { var allTemperatures = new List<float>(); float coreTemperature = -1; string temperatureName = null; switch (hardware.HardwareType) { case HardwareType.Cpu: temperatureName = "Core Average"; break; case HardwareType.GpuNvidia: case HardwareType.GpuAmd: case HardwareType.GpuIntel: temperatureName = "GPU Core"; break; default: break; } foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Temperature) { if (sensor.Value.HasValue) { float currentTemperature = (float)sensor.Value; allTemperatures.Add(currentTemperature); if (sensor.Name == temperatureName) { coreTemperature = currentTemperature; } } } } if (coreTemperature >= 0) { temperature = coreTemperature; return true; } if (allTemperatures.Count > 0) { float sum = 0; foreach (var temp in allTemperatures) { sum += temp; } temperature = sum / allTemperatures.Count; return true; } // 如果没有找到温度传感器,在子硬件中寻找 foreach (var subHardware in hardware.SubHardware) { if (GetHardwareTemperature(subHardware, ref temperature)) { return true; } } return false; } // 计算 GPU 利用率 public bool GetGpuUsage(IHardware hardware, ref float gpuUsage) { foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Load && sensor.Name == "GPU Core") { float currentGpuUsage = Convert.ToSingle(sensor.Value); if (gpuUsage < currentGpuUsage) { gpuUsage = currentGpuUsage; } } } return gpuUsage > 0; } // 计算硬盘利用率 public bool GetHddUsage(IHardware hardware, ref float hddUsage) { foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Load && sensor.Name == "Used Space") { hddUsage = Convert.ToSingle(sensor.Value); return true; } } return false; } // 计算风扇转速 public bool GetFanSpeed(IHardware hardware, ref float fanSpeed) { m_all_fan_speed.Clear(); foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Fan) { string name = sensor.Name; float speed = Convert.ToSingle(sensor.Value); m_all_fan_speed[name] = speed; if (speed > fanSpeed) { fanSpeed = speed; } } } return fanSpeed > 0; } // 计算网络上下行速率 public bool GetNetworkSpeed(IHardware hardware, ref float outSpeed, ref float inSpeed) { bool flag = false; foreach (var sensor in hardware.Sensors) { if (sensor.SensorType == SensorType.Throughput) { if (sensor.Name == "Upload Speed") { float speed = Convert.ToSingle(sensor.Value); if (outSpeed < speed) { outSpeed = speed; } flag = true; } else if (sensor.Name == "Download Speed") { float speed = Convert.ToSingle(sensor.Value); if (inSpeed < speed) { inSpeed = speed; } flag = true; } } } return flag; } // 函数:GetHardwareInfo // 描述:递归地获取硬件信息并打印到控制台 // 参数:IHardware hardware - 当前硬件对象 // 返回值:int - 成功返回0,失败返回-1 public int GetHardwareInfo(IHardware hardware) { try { hardware.Update(); // 更新硬件数据 // 根据硬件类型执行不同的操作 switch (hardware.HardwareType) { case HardwareType.Cpu: // CPU 信息 { // 获取 CPU 利用率 if (m_cpu_usage < 0) GetCpuUsage(hardware, ref m_cpu_usage); // 获取 CPU 温度 if (m_cpu_temperature < 0) GetCpuTemperature(hardware, ref m_cpu_temperature); // 获取 CPU 频率 if (m_cpu_freq < 0) GetCPUFreq(hardware, ref m_cpu_freq); break; } case HardwareType.GpuIntel: // Intel GPU 信息 case HardwareType.GpuNvidia: // NVIDIA GPU 信息 case HardwareType.GpuAmd: // AMD GPU 信息 { // 获取 GPU 温度 if (m_gpu_temperature < 0) GetHardwareTemperature(hardware, ref m_gpu_temperature); // 获取 GPU 利用率 if (m_gpu_usage < 0) GetGpuUsage(hardware, ref m_gpu_usage); break; } case HardwareType.Memory: // 内存信息 { // 获取内存利用率 if (m_memory_usage < 0) GetMemoryUsage(hardware, ref m_memory_usage); break; } case HardwareType.Motherboard: // 主板信息 { // 获取主板温度 if (m_main_board_temperature < 0) GetHardwareTemperature(hardware, ref m_main_board_temperature); break; } case HardwareType.Storage: // 存储设备信息 { // 获取硬盘温度 float curHddTemperature = -1; GetHardwareTemperature(hardware, ref curHddTemperature); InsertValueToDictionary(m_all_hdd_temperature, ClrStringToStdWstring(hardware.Name), curHddTemperature); if (m_hdd_temperature < curHddTemperature) m_hdd_temperature = curHddTemperature; // 获取硬盘利用率 float curHddUsage = -1; GetHddUsage(hardware, ref curHddUsage); InsertValueToDictionary(m_all_hdd_usage, ClrStringToStdWstring(hardware.Name), curHddUsage); if (m_hdd_usage < curHddUsage) m_hdd_usage = curHddUsage; break; } case HardwareType.Network: // 网络设备信息 { // 获取网络速率 GetNetworkSpeed(hardware, ref m_out_speed, ref m_in_speed); break; } case HardwareType.SuperIO: // SuperIO 信息 { // 计算风扇转速 if (m_fan_speed < 0) GetFanSpeed(hardware, ref m_fan_speed); break; } default: // 未知硬件类型 { // 未知硬件类型 break; } } // 如果硬件有子硬件,递归调用该函数处理子硬件信息 foreach (var subHardware in hardware.SubHardware) { GetHardwareInfo(subHardware); } } catch (Exception ex) { // 捕获并打印异常信息 Console.WriteLine("Error: " + ex.Message); return -1; } return 0; // 操作成功 } }
(2)程序入口类 Program.cs 代码如下:
using System; using System.Threading; class Program { static void Main() { // 创建硬件监控实例 HardwareMonitor hardwareMonitor = HardwareMonitor.Instance; hardwareMonitor.GetComputer().Open(); // 打开硬件监控 while (true) { // 重置所有值 hardwareMonitor.ResetAllValues(); // 遍历所有硬件并获取信息 foreach (var hardware in hardwareMonitor.GetComputer().Hardware) { hardwareMonitor.GetHardwareInfo(hardware); } // 输出所有值 hardwareMonitor.PrintAllValues(); // 延迟 5 秒后继续监控 Thread.Sleep(5000); } // 关闭硬件监控 hardwareMonitor.GetComputer().Close(); } }
全部评论(0)