// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
///
/// 处理器帮助类
///
public static class CpuHelper
{
///
/// 处理器信息
///
///
/// 推荐使用,默认有缓存
///
public static CpuInfo CpuInfos => Cache.Default.GetOrAdd("CpuInfos", _ => GetCpuInfos(), 5 * 60);
///
/// 获取处理器信息
///
///
public static CpuInfo GetCpuInfos()
{
var cpuInfo = new CpuInfo
{
LogicalCoreCount = Environment.ProcessorCount,
ProcessorArchitecture = RuntimeInformation.ProcessArchitecture.ToString()
};
try
{
// 获取CPU使用率
GetCpuUsage(cpuInfo);
// 获取CPU详细信息
GetCpuDetails(cpuInfo);
// 获取温度信息(如果可用)
GetCpuTemperature(cpuInfo);
}
catch (Exception ex)
{
Log.Error("获取处理器信息出错," + ex.Message);
}
return cpuInfo;
}
///
/// 获取CPU使用率
///
///
private static void GetCpuUsage(CpuInfo cpuInfo)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
var output = ShellHelper.Bash(@"top -b -n1 | grep ""Cpu(s)""").Trim();
var lines = output.Split(',');
if (lines.Length > 3)
{
var loadPercentage = lines[3].Trim().Split(' ')[0].Replace("%", "");
if (double.TryParse(loadPercentage, out var usage))
{
cpuInfo.UsagePercentage = Math.Round(100 - usage, 2); // idle转换为使用率
}
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var output = ShellHelper.Bash(@"top -l 1 -F | awk '/CPU usage/ {gsub(""%"", """"); print $7}'").Trim();
if (double.TryParse(output, out var usage))
{
cpuInfo.UsagePercentage = Math.Round(100 - usage, 2); // idle转换为使用率
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// 使用WMI获取CPU使用率
try
{
var output = ShellHelper.Cmd("wmic", "cpu get LoadPercentage /Value").Trim();
var lines = output.Split(Environment.NewLine);
var loadLine = lines.FirstOrDefault(s => s.StartsWith("LoadPercentage="));
if (loadLine != null)
{
var loadPercentage = loadLine.Split('=')[1].Trim();
if (double.TryParse(loadPercentage, out var usage))
{
cpuInfo.UsagePercentage = Math.Round(usage, 2);
}
}
}
catch
{
// 如果WMI失败,使用默认值
cpuInfo.UsagePercentage = 0;
}
}
}
///
/// 获取CPU温度信息(如果可用)
///
///
private static void GetCpuTemperature(CpuInfo cpuInfo)
{
try
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
// 尝试从thermal_zone获取温度
var thermalFiles = Directory.GetFiles("/sys/class/thermal", "thermal_zone*");
foreach (var file in thermalFiles)
{
var tempFile = Path.Combine(file, "temp");
if (File.Exists(tempFile))
{
var tempStr = File.ReadAllText(tempFile).Trim();
if (int.TryParse(tempStr, out var temp))
{
cpuInfo.Temperature = Math.Round(temp / 1000.0, 1);
break;
}
}
}
}
// Windows和macOS的温度获取需要特殊权限或第三方工具,这里暂不实现
}
catch
{
// 温度获取失败不影响其他信息
}
}
///
/// 获取CPU详细信息
///
///
private static void GetCpuDetails(CpuInfo cpuInfo)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
var cpuInfoOutput = ShellHelper.Bash("cat /proc/cpuinfo").Trim();
var lines = cpuInfoOutput.Split('\n');
foreach (var line in lines)
{
if (line.StartsWith("model name"))
{
cpuInfo.ProcessorName = line.Split(':')[1].Trim();
}
else if (line.StartsWith("cpu MHz"))
{
if (double.TryParse(line.Split(':')[1].Trim(), out var mhz))
{
cpuInfo.BaseClockSpeed = Math.Round(mhz / 1000, 2);
}
}
else if (line.StartsWith("cache size"))
{
cpuInfo.CacheBytes = line.Split(':')[1].Trim().ParseToLong();
}
else if (line.StartsWith("cpu cores"))
{
if (int.TryParse(line.Split(':')[1].Trim(), out var cores))
{
cpuInfo.PhysicalCoreCount = cores;
}
}
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var nameOutput = ShellHelper.Bash("sysctl -n machdep.cpu.brand_string").Trim();
cpuInfo.ProcessorName = nameOutput;
var coreOutput = ShellHelper.Bash("sysctl -n hw.physicalcpu").Trim();
if (int.TryParse(coreOutput, out var cores))
{
cpuInfo.PhysicalCoreCount = cores;
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var output = ShellHelper.Cmd("wmic", "cpu get Name,NumberOfCores,MaxClockSpeed,L3CacheSize /Value").Trim();
var lines = output.Split(Environment.NewLine);
foreach (var line in lines)
{
if (line.StartsWith("Name="))
{
cpuInfo.ProcessorName = line.Split('=')[1].Trim();
}
else if (line.StartsWith("NumberOfCores="))
{
if (int.TryParse(line.Split('=')[1], out var cores))
{
cpuInfo.PhysicalCoreCount = cores;
}
}
else if (line.StartsWith("MaxClockSpeed="))
{
if (double.TryParse(line.Split('=')[1], out var mhz))
{
cpuInfo.BaseClockSpeed = Math.Round(mhz / 1000, 2);
}
}
else if (line.StartsWith("L3CacheSize="))
{
var cache = line.Split('=')[1].Trim();
if (!string.IsNullOrEmpty(cache) && cache != "0")
{
cpuInfo.CacheBytes = cache.ParseToLong() * 1024;
}
}
}
}
}
}
///
/// 处理器信息
///
public record CpuInfo
{
///
/// 处理器名称
///
public string ProcessorName { get; set; } = string.Empty;
///
/// 处理器架构
///
public string ProcessorArchitecture { get; set; } = string.Empty;
///
/// 物理核心数
///
public int PhysicalCoreCount { get; set; }
///
/// 逻辑核心数(超线程)
///
public int LogicalCoreCount { get; set; }
///
/// 基础时钟频率(GHz)
///
public double BaseClockSpeed { get; set; }
///
/// 缓存大小
///
public long CacheBytes { get; set; }
///
/// CPU使用率(%)
///
public double UsagePercentage { get; set; }
///
/// CPU温度(°C)
///
public double? Temperature { get; set; }
}