using Hardware.Info; using NAudio.CoreAudioApi; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Runtime.InteropServices; using System.Threading.Tasks; namespace XiaoZhiSharp.Utils { /// /// 主程序类 /// 提供用户界面和主循环 /// public class SystemMonitorTest { private static void getVolume() { MMDeviceEnumerator enumerator = new MMDeviceEnumerator(); // 获取默认扬声器设备 MMDevice defaultSpeaker = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); float speakerVolume = defaultSpeaker.AudioEndpointVolume.MasterVolumeLevelScalar; // 获取默认麦克风设备 MMDevice defaultMicrophone = enumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications); float microphoneVolume = defaultMicrophone.AudioEndpointVolume.MasterVolumeLevelScalar; Console.WriteLine("扬声器音量:" + speakerVolume + "\n" + "麦克风音量:" + microphoneVolume); } private static void HardwareInfoLib(bool test) { getVolume(); IHardwareInfo hardwareInfo = new Hardware.Info.HardwareInfo(); hardwareInfo.RefreshOperatingSystem(); hardwareInfo.RefreshMemoryStatus(); hardwareInfo.RefreshBatteryList(); hardwareInfo.RefreshBIOSList(); hardwareInfo.RefreshComputerSystemList(); hardwareInfo.RefreshCPUList(includePercentProcessorTime: test); hardwareInfo.RefreshDriveList(); hardwareInfo.RefreshKeyboardList(); hardwareInfo.RefreshMemoryList(); hardwareInfo.RefreshMonitorList(); hardwareInfo.RefreshMotherboardList(); hardwareInfo.RefreshMouseList(); hardwareInfo.RefreshNetworkAdapterList(includeBytesPerSec: test, includeNetworkAdapterConfiguration: test); hardwareInfo.RefreshPrinterList(); hardwareInfo.RefreshSoundDeviceList(); hardwareInfo.RefreshVideoControllerList(); //hardwareInfo.RefreshAll(); Console.WriteLine(hardwareInfo.OperatingSystem); Console.WriteLine(hardwareInfo.MemoryStatus); foreach (var hardware in hardwareInfo.BatteryList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.BiosList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.ComputerSystemList) Console.WriteLine(hardware); foreach (var cpu in hardwareInfo.CpuList) { Console.WriteLine(cpu); foreach (var cpuCore in cpu.CpuCoreList) Console.WriteLine(cpuCore); } 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.KeyboardList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.MemoryList) Console.WriteLine(hardware); if (hardwareInfo.MemoryList.Count > 0) { var memoryStatus = hardwareInfo.MemoryStatus; //memoryStatus. // 计算内存占用率 double usagePercentage = ((double)memoryStatus.TotalPhysical - memoryStatus.AvailablePhysical) / memoryStatus.TotalPhysical * 100; Console.WriteLine($"总物理内存: {FormatBytes(memoryStatus.TotalPhysical)}"); Console.WriteLine($"可用内存: {FormatBytes(memoryStatus.AvailablePhysical)}"); Console.WriteLine($"已用内存: {FormatBytes(memoryStatus.TotalPhysical - memoryStatus.AvailablePhysical)}"); Console.WriteLine($"内存占用率: {usagePercentage:F2}%"); } else { Console.WriteLine("无法获取内存信息"); } foreach (var hardware in hardwareInfo.MonitorList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.MotherboardList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.MouseList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.NetworkAdapterList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.PrinterList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.SoundDeviceList) Console.WriteLine(hardware); foreach (var hardware in hardwareInfo.VideoControllerList) Console.WriteLine(hardware); foreach (var address in Hardware.Info.HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Ethernet, OperationalStatus.Up)) Console.WriteLine(address); Console.WriteLine(); foreach (var address in Hardware.Info.HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Wireless80211)) Console.WriteLine(address); Console.WriteLine(); foreach (var address in Hardware.Info.HardwareInfo.GetLocalIPv4Addresses(OperationalStatus.Up)) Console.WriteLine(address); Console.WriteLine(); foreach (var address in Hardware.Info.HardwareInfo.GetLocalIPv4Addresses()) Console.WriteLine(address); Console.ReadLine(); } /// /// 主入口点 /// public static async Task RunTest(string[] args) { HardwareInfoLib(true); HardwareInfoLib(false); Console.WriteLine("系统监控工具 - 按任意键退出"); Console.WriteLine("=========================================="); // 创建系统监控器实例 var monitor = new OSSystemMonitor(); // 主监控循环 while (!Console.KeyAvailable) { try { // 异步获取系统信息 var info = await monitor.GetSystemInfoAsync(); // 显示系统信息 Console.WriteLine($"操作系统: {info.OSPlatform}"); var cpuUsage = $"CPU使用率: {info.CpuUsage}-"; if (cpuUsage.EndsWith("%%")) { } Console.WriteLine(cpuUsage); Console.WriteLine($"内存使用: {FormatBytes((ulong)info.UsedMemory)} / {FormatBytes((ulong)info.TotalMemory)} ({info.MemoryUsage}%)"); Console.WriteLine($"磁盘使用: {FormatBytes((ulong)info.UsedDiskSpace)} / {FormatBytes((ulong)info.TotalDiskSpace)} ({info.DiskUsage}%)"); Console.WriteLine("=========================================="); // 等待2秒后更新 await Task.Delay(500); // 移动光标到开头,覆盖上次的输出 if (Console.CursorTop >= 5) { Console.SetCursorPosition(0, Console.CursorTop - 5); } } catch (Exception ex) { // 显示错误信息并继续运行 Console.WriteLine($"错误: {ex.Message}"); await Task.Delay(500); } } } /// /// 格式化字节数为易读的字符串 /// 自动选择合适的单位(B, KB, MB, GB, TB) /// /// 字节数 /// 格式化后的字符串 private static string FormatBytes(ulong bytes) { if (bytes == 0) return "0 B"; string[] suffixes = { "B", "KB", "MB", "GB", "TB" }; int counter = 0; decimal number = bytes; // 循环除以1024,直到找到合适的单位 while (Math.Round(number / 1024) >= 1 && counter < suffixes.Length - 1) { number /= 1024; counter++; } // 返回格式化后的字符串(保留1位小数) return $"{number:n1} {suffixes[counter]}"; } } /// /// 系统信息数据模型类 /// 用于存储和传递CPU、内存、磁盘的使用信息 /// public class OSSystemInfo { /// CPU使用率百分比 public double CpuUsage { get; set; } /// 内存使用率百分比 public double MemoryUsage { get; set; } /// 总物理内存大小(字节) public long TotalMemory { get; set; } /// 已使用内存大小(字节) public long UsedMemory { get; set; } /// 磁盘使用率百分比 public double DiskUsage { get; set; } /// 总磁盘空间大小(字节) public long TotalDiskSpace { get; set; } /// 已使用磁盘空间大小(字节) public long UsedDiskSpace { get; set; } /// 可用磁盘空间大小(字节) public long AvailableDiskSpace { get; set; } /// 操作系统平台名称 public string OSPlatform { get; set; } = ""; } /// /// 系统监控器类 /// 提供跨平台的CPU、内存、磁盘使用率监控功能 /// public class OSSystemMonitor { // 用于计算CPU使用率的时间戳和处理器时间 private DateTime _lastCpuTime; private TimeSpan _lastTotalProcessorTime; private Process _process; // 用于Linux系统CPU使用率计算的缓存值 private ulong _lastTotalCpuTime = 0; private ulong _lastTotalIdle = 0; /// /// 构造函数,初始化监控器 /// public OSSystemMonitor() { // 获取当前进程实例,用于计算进程相关的系统资源使用情况 _process = Process.GetCurrentProcess(); // 初始化时间戳,用于后续计算CPU使用率 _lastCpuTime = DateTime.Now; _lastTotalProcessorTime = _process.TotalProcessorTime; } /// /// 异步获取系统信息 /// 同时获取CPU、内存、磁盘的使用信息 /// /// 包含系统信息的OSSystemInfo对象 public async Task GetSystemInfoAsync() { var info = new OSSystemInfo { OSPlatform = GetOSPlatform() }; // 使用Task.WhenAll并行获取各项系统信息,提高效率 await Task.WhenAll( Task.Run(() => info.CpuUsage = GetCpuUsage()), Task.Run(() => GetMemoryInfo(info)), Task.Run(() => GetDiskInfo(info)) ); return info; } /// /// 获取CPU使用率 /// 根据操作系统平台调用不同的实现 /// /// CPU使用率百分比 private double GetCpuUsage() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return GetWindowsCpuUsage(); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return GetLinuxCpuUsage(); } return 0; // 未知平台返回0 } /// /// Windows平台获取CPU使用率 /// 使用PerformanceCounter性能计数器 /// /// CPU使用率百分比 private double GetWindowsCpuUsage() { try { // 创建性能计数器实例,监控总处理器时间 using (var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total")) { // 首次调用NextValue()初始化计数器,返回的值通常不准确 cpuCounter.NextValue(); // 等待1秒让计数器收集足够的数据 System.Threading.Thread.Sleep(1000); // 第二次调用获取准确的CPU使用率 return Math.Round(cpuCounter.NextValue(), 2); } } catch { // 如果性能计数器不可用,使用备用的计算方法 return CalculateCpuUsage(); } } /// /// 备用的CPU使用率计算方法 /// 通过计算进程的处理器时间变化来估算CPU使用率 /// /// 估算的CPU使用率百分比 private double CalculateCpuUsage() { var currentTime = DateTime.Now; var currentTotalProcessorTime = _process.TotalProcessorTime; // 计算时间间隔内使用的CPU时间(毫秒) var cpuUsedMs = (currentTotalProcessorTime - _lastTotalProcessorTime).TotalMilliseconds; // 计算经过的总时间(毫秒) var totalMsPassed = (currentTime - _lastCpuTime).TotalMilliseconds; // 更新上一次的时间戳 _lastCpuTime = currentTime; _lastTotalProcessorTime = currentTotalProcessorTime; // 避免除以零错误 if (totalMsPassed == 0) return 0; // 计算CPU使用率:使用的CPU时间 / (CPU核心数 * 总时间) var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed); // 转换为百分比并四舍五入到两位小数 return Math.Round(cpuUsageTotal * 100, 2); } /// /// Linux平台获取CPU使用率 /// 通过解析/proc/stat文件来计算 /// /// CPU使用率百分比 private double GetLinuxCpuUsage() { try { // 读取/proc/stat文件,包含CPU统计信息 var lines = File.ReadAllLines("/proc/stat"); // 查找以"cpu "开头的行(总CPU统计) var cpuLine = lines.FirstOrDefault(l => l.StartsWith("cpu ")); if (cpuLine == null) return 0; // 分割字符串,移除空条目 var values = cpuLine.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (values.Length < 8) return 0; // 解析各个时间字段(单位:jiffies,通常为10ms) var user = ulong.Parse(values[1]); // 用户模式时间 var nice = ulong.Parse(values[2]); // 低优先级用户模式时间 var system = ulong.Parse(values[3]); // 系统模式时间 var idle = ulong.Parse(values[4]); // 空闲时间 var iowait = ulong.Parse(values[5]); // I/O等待时间 var irq = ulong.Parse(values[6]); // 中断处理时间 var softirq = ulong.Parse(values[7]); // 软中断处理时间 // 计算总CPU时间和总空闲时间 var totalCpuTime = user + nice + system + idle + iowait + irq + softirq; var totalIdle = idle + iowait; // 如果是第一次调用,初始化缓存值并等待1秒后重新计算 if (_lastTotalCpuTime == 0) { _lastTotalCpuTime = totalCpuTime; _lastTotalIdle = totalIdle; System.Threading.Thread.Sleep(1000); return GetLinuxCpuUsage(); // 递归调用获取第二次读数 } // 计算两次读数之间的差值 var totalCpuDiff = totalCpuTime - _lastTotalCpuTime; var totalIdleDiff = totalIdle - _lastTotalIdle; // 更新缓存值 _lastTotalCpuTime = totalCpuTime; _lastTotalIdle = totalIdle; // 避免除以零错误 if (totalCpuDiff == 0) return 0; // 计算CPU使用率:(1 - 空闲时间比例) * 100 var cpuUsage = (1.0 - (double)totalIdleDiff / totalCpuDiff) * 100; return Math.Round(cpuUsage, 2); } catch { // 如果读取/proc/stat失败,使用备用的计算方法 return CalculateCpuUsage(); } } /// /// 获取内存信息并填充到OSSystemInfo对象 /// 根据操作系统平台调用不同的实现 /// /// 要填充的OSSystemInfo对象 private void GetMemoryInfo(OSSystemInfo info) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { GetWindowsMemoryInfo(info); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { GetLinuxMemoryInfo(info); } } /// /// Windows平台获取内存信息 /// 使用PerformanceCounter性能计数器 /// /// 要填充的OSSystemInfo对象 private void GetWindowsMemoryInfo(OSSystemInfo info) { try { // 使用性能计数器获取可用内存字节数 using (var memCounter = new PerformanceCounter("Memory", "Available Bytes")) { var availableMemory = memCounter.NextValue(); var totalMemory = GetTotalPhysicalMemory(); info.TotalMemory = totalMemory; info.UsedMemory = totalMemory - (long)availableMemory; // 计算内存使用率百分比 if (totalMemory > 0) { info.MemoryUsage = Math.Round((double)info.UsedMemory / totalMemory * 100, 2); } else { info.MemoryUsage = 0; } } } catch { // 如果性能计数器不可用,使用Windows API备选方案 GetWindowsMemoryInfoAlternative(info); } } /// /// Windows平台备用的内存信息获取方法 /// 使用Windows API GlobalMemoryStatusEx /// /// 要填充的OSSystemInfo对象 private void GetWindowsMemoryInfoAlternative(OSSystemInfo info) { try { // 创建内存状态结构体 var memoryStatus = new MEMORYSTATUSEX(); memoryStatus.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); // 调用Windows API获取内存状态 if (GlobalMemoryStatusEx(ref memoryStatus)) { info.TotalMemory = (long)memoryStatus.ullTotalPhys; info.UsedMemory = (long)(memoryStatus.ullTotalPhys - memoryStatus.ullAvailPhys); // 计算内存使用率百分比 if (info.TotalMemory > 0) { info.MemoryUsage = Math.Round((double)info.UsedMemory / info.TotalMemory * 100, 2); } else { info.MemoryUsage = 0; } } } catch { // 如果所有方法都失败,使用进程工作集作为近似值 info.TotalMemory = GetTotalPhysicalMemory(); info.UsedMemory = Environment.WorkingSet; if (info.TotalMemory > 0) { info.MemoryUsage = Math.Round((double)info.UsedMemory / info.TotalMemory * 100, 2); } else { info.MemoryUsage = 0; } } } /// /// Linux平台获取内存信息 /// 通过解析/proc/meminfo文件 /// /// 要填充的OSSystemInfo对象 private void GetLinuxMemoryInfo(OSSystemInfo info) { try { // 读取/proc/meminfo文件,包含内存统计信息 var lines = File.ReadAllLines("/proc/meminfo"); var memInfo = new Dictionary(); // 解析每行数据 foreach (var line in lines) { var parts = line.Split(':', StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { var key = parts[0].Trim(); var valueString = parts[1].Trim().Split(' ')[0]; // 转换值(文件中的单位是KB,转换为字节) if (long.TryParse(valueString, out long value)) { memInfo[key] = value * 1024; } } } // 优先使用MemAvailable(更准确反映可用内存) if (memInfo.ContainsKey("MemTotal") && memInfo.ContainsKey("MemAvailable")) { info.TotalMemory = memInfo["MemTotal"]; info.UsedMemory = memInfo["MemTotal"] - memInfo["MemAvailable"]; if (info.TotalMemory > 0) { info.MemoryUsage = Math.Round((double)info.UsedMemory / info.TotalMemory * 100, 2); } } else if (memInfo.ContainsKey("MemTotal") && memInfo.ContainsKey("MemFree")) { // 如果没有MemAvailable,使用MemFree作为近似值 info.TotalMemory = memInfo["MemTotal"]; info.UsedMemory = memInfo["MemTotal"] - memInfo["MemFree"]; if (info.TotalMemory > 0) { info.MemoryUsage = Math.Round((double)info.UsedMemory / info.TotalMemory * 100, 2); } } } catch { // 发生错误时清零相关字段 info.MemoryUsage = 0; info.TotalMemory = 0; info.UsedMemory = 0; } } /// /// 获取磁盘信息并填充到OSSystemInfo对象 /// 自动识别系统盘(Windows)或根分区(Linux) /// /// 要填充的OSSystemInfo对象 private void GetDiskInfo(OSSystemInfo info) { try { DriveInfo systemDrive; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // Windows:选择系统目录所在的驱动器 systemDrive = DriveInfo.GetDrives() .FirstOrDefault(d => d.IsReady && d.Name.Equals(Path.GetPathRoot(Environment.SystemDirectory), StringComparison.OrdinalIgnoreCase)); } else { // Linux/macOS:首先尝试找到根目录所在的驱动器 systemDrive = DriveInfo.GetDrives() .FirstOrDefault(d => d.IsReady && d.RootDirectory.FullName == "/"); // 如果没找到根分区,选择第一个可用的固定驱动器 systemDrive ??= DriveInfo.GetDrives() .FirstOrDefault(d => d.IsReady && d.DriveType == DriveType.Fixed); } // 如果找到系统盘且就绪,读取磁盘信息 if (systemDrive != null && systemDrive.IsReady) { info.TotalDiskSpace = systemDrive.TotalSize; info.AvailableDiskSpace = systemDrive.AvailableFreeSpace; info.UsedDiskSpace = systemDrive.TotalSize - systemDrive.AvailableFreeSpace; // 计算磁盘使用率百分比 if (systemDrive.TotalSize > 0) { info.DiskUsage = Math.Round((double)info.UsedDiskSpace / systemDrive.TotalSize * 100, 2); } else { info.DiskUsage = 0; } } } catch { // 发生错误时清零相关字段 info.DiskUsage = 0; info.TotalDiskSpace = 0; info.UsedDiskSpace = 0; info.AvailableDiskSpace = 0; } } /// /// 获取总物理内存大小 /// 跨平台实现,支持Windows和Linux /// /// 总物理内存字节数 private long GetTotalPhysicalMemory() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { try { // Windows平台使用GlobalMemoryStatusEx API var memoryStatus = new MEMORYSTATUSEX(); memoryStatus.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); if (GlobalMemoryStatusEx(ref memoryStatus)) { return (long)memoryStatus.ullTotalPhys; } } catch { // 忽略错误,返回0 } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { try { // Linux/macOS平台读取/proc/meminfo文件 var lines = File.ReadAllLines("/proc/meminfo"); var totalLine = lines.FirstOrDefault(l => l.StartsWith("MemTotal")); if (totalLine != null) { var parts = totalLine.Split(':', StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { var valueString = parts[1].Trim().Split(' ')[0]; if (long.TryParse(valueString, out long value)) { return value * 1024; // 转换为字节 } } } } catch { // 忽略错误,返回0 } } return 0; // 默认返回0 } /// /// 获取操作系统平台名称 /// /// 操作系统平台名称字符串 private string GetOSPlatform() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return "Windows"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) return "Linux"; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) return "macOS"; return "Unknown"; } // Windows API 结构体,用于获取内存状态信息 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct MEMORYSTATUSEX { public uint dwLength; // 结构体大小 public uint dwMemoryLoad; // 内存使用率百分比 public ulong ullTotalPhys; // 总物理内存 public ulong ullAvailPhys; // 可用物理内存 public ulong ullTotalPageFile; // 总页面文件大小 public ulong ullAvailPageFile; // 可用页面文件大小 public ulong ullTotalVirtual; // 总虚拟内存 public ulong ullAvailVirtual; // 可用虚拟内存 public ulong ullAvailExtendedVirtual; // 可用扩展虚拟内存 } // Windows API 函数导入,用于获取全局内存状态 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); } }