308 lines
9.8 KiB
C#
Raw Normal View History

2025-10-11 18:25:59 +08:00
/*
* <copyright>
Company="公司"
2020-2025
Author=JCH
Path=XiaoZhiSharp.Utils.SystemMonitor.cs
* <copyright>
* --------------------------------------------------------------
* JCH
* SystemMonitor.cs
* V1.0.0.0
* JCH
* 2025/9/27 9:33:01
*
* --------------------------------------------------------------
* 2025/9/27 9:33:01
* JCH
* V1.0.0.0
*
* --------------------------------------------------------------
*/
using LibreHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace XiaoZhiSharp.Utils
{
public class SystemMonitor : IDisposable
{
private Computer _computer;
private readonly Dictionary<SensorType, List<ISensor>> _sensors;
private bool _isMonitoring;
private Task _monitoringTask;
private CancellationTokenSource _cancellationTokenSource;
public SystemMonitor()
{
_sensors = new Dictionary<SensorType, List<ISensor>>();
InitializeComputer();
}
private void InitializeComputer()
{
_computer = new Computer
{
//IsCpuEnabled = true,
IsGpuEnabled = true,
//IsMemoryEnabled = true,
//IsMotherboardEnabled = true,
//IsControllerEnabled = true,
//IsNetworkEnabled = true,
//IsStorageEnabled = true
};
_computer.Open();
_computer.Accept(new UpdateVisitor());
}
public HardwareInfo GetHardwareInfo()
{
UpdateAllSensors();
return new HardwareInfo
{
//CpuUsage = GetCpuUsage(),
GpuUsage = GetGpuUsage(),
//MemoryUsage = GetMemoryUsage(),
//DiskUsage = GetDiskUsage(),
Timestamp = DateTime.Now
};
}
private void UpdateAllSensors()
{
foreach (var hardware in _computer.Hardware)
{
hardware.Update();
}
}
private float GetCpuUsage()
{
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.Cpu)
{
var loadSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Load && s.Name.Contains("CPU Total"));
if (loadSensor != null && loadSensor.Value.HasValue)
{
return loadSensor.Value.Value;
}
}
}
return 0;
}
private float GetGpuUsage()
{
// 检查NVIDIA GPU
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.GpuNvidia)
{
var loadSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Load);
if (loadSensor != null && loadSensor.Value.HasValue)
{
return loadSensor.Value.Value;
}
}
}
// 检查AMD GPU
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.GpuAmd)
{
var loadSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Load);
if (loadSensor != null && loadSensor.Value.HasValue)
{
return loadSensor.Value.Value;
}
}
}
// 检查Intel集成显卡
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.GpuIntel)
{
var loadSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Load);
if (loadSensor != null && loadSensor.Value.HasValue)
{
return loadSensor.Value.Value;
}
}
}
return 0;
}
private MemoryInfo GetMemoryUsage()
{
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.Memory)
{
var memoryInfo = new MemoryInfo();
// 获取已使用内存
var usedMemorySensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Data && s.Name.Contains("Used"));
// 获取可用内存
var availableMemorySensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Data && s.Name.Contains("Available"));
if (usedMemorySensor != null && usedMemorySensor.Value.HasValue)
{
memoryInfo.UsedGB = usedMemorySensor.Value.Value / 1024; // 转换为GB
}
if (availableMemorySensor != null && availableMemorySensor.Value.HasValue)
{
memoryInfo.AvailableGB = availableMemorySensor.Value.Value / 1024;
}
memoryInfo.UsagePercentage = memoryInfo.TotalGB > 0 ?
(memoryInfo.UsedGB / memoryInfo.TotalGB) * 100 : 0;
return memoryInfo;
}
}
return new MemoryInfo();
}
private DiskInfo GetDiskUsage()
{
var diskInfo = new DiskInfo();
foreach (var hardware in _computer.Hardware)
{
if (hardware.HardwareType == HardwareType.Storage)
{
// 获取磁盘负载
var loadSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Load);
if (loadSensor != null && loadSensor.Value.HasValue)
{
diskInfo.LoadPercentage = loadSensor.Value.Value;
}
// 获取磁盘读写速度
var readRateSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Throughput && s.Name.Contains("Read"));
var writeRateSensor = hardware.Sensors
.FirstOrDefault(s => s.SensorType == SensorType.Throughput && s.Name.Contains("Write"));
if (readRateSensor != null && readRateSensor.Value.HasValue)
{
diskInfo.ReadRateMBs = readRateSensor.Value.Value / 1024 / 1024;
}
if (writeRateSensor != null && writeRateSensor.Value.HasValue)
{
diskInfo.WriteRateMBs = writeRateSensor.Value.Value / 1024 / 1024;
}
break; // 只获取第一个存储设备的信息
}
}
return diskInfo;
}
public void StartContinuousMonitoring(Action<HardwareInfo> updateCallback, int intervalMs = 1000)
{
if (_isMonitoring) return;
_isMonitoring = true;
_cancellationTokenSource = new CancellationTokenSource();
_monitoringTask = Task.Run(async () =>
{
while (_isMonitoring && !_cancellationTokenSource.Token.IsCancellationRequested)
{
var info = GetHardwareInfo();
updateCallback?.Invoke(info);
await Task.Delay(intervalMs, _cancellationTokenSource.Token);
}
});
}
public void StopContinuousMonitoring()
{
_isMonitoring = false;
_cancellationTokenSource?.Cancel();
_monitoringTask?.Wait(1000);
}
public void Dispose()
{
StopContinuousMonitoring();
_computer?.Close();
}
}
// 更新访问器类
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (var subHardware in hardware.SubHardware)
{
subHardware.Accept(this);
}
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
// 数据模型类
public class HardwareInfo
{
public float CpuUsage { get; set; } // CPU使用率百分比
public float GpuUsage { get; set; } // GPU使用率百分比
public MemoryInfo MemoryUsage { get; set; } // 内存使用信息
public DiskInfo DiskUsage { get; set; } // 磁盘使用信息
public DateTime Timestamp { get; set; }
}
public class MemoryInfo
{
public float UsedGB { get; set; }
public float AvailableGB { get; set; }
public float TotalGB => UsedGB + AvailableGB;
public float UsagePercentage { get; set; }
}
public class DiskInfo
{
public float LoadPercentage { get; set; } // 磁盘负载百分比
public float ReadRateMBs { get; set; } // 读取速度 MB/s
public float WriteRateMBs { get; set; } // 写入速度 MB/s
}
}