using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using AxCopilot.SDK; namespace AxCopilot.Handlers; public class MonitorHandler : IActionHandler { 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; } public string? Prefix => "monitor"; public PluginMetadata Metadata => new PluginMetadata("Monitor", "시스템 리소스 모니터 — monitor", "1.0", "AX"); [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); public Task> GetItemsAsync(string query, CancellationToken ct) { string text = query.Trim().ToLowerInvariant(); List list = new List(); bool flag = string.IsNullOrWhiteSpace(text); if (flag || text.Contains("cpu") || text.Contains("프로세서")) { int processorCount = Environment.ProcessorCount; int value = Process.GetProcesses().Length; int value2 = 0; try { value2 = Process.GetProcesses().Sum(delegate(Process p) { try { return p.Threads.Count; } catch { return 0; } }); } catch { } list.Add(new LauncherItem($"CPU: {processorCount}코어 · 프로세스 {value}개 · 스레드 {value2:N0}개", "Enter로 클립보드 복사", null, $"CPU: {processorCount}코어, 프로세스 {value}개, 스레드 {value2:N0}개", null, "\ue950")); } if (flag || text.Contains("mem") || text.Contains("ram") || text.Contains("메모리")) { MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX { dwLength = (uint)Marshal.SizeOf() }; GlobalMemoryStatusEx(ref lpBuffer); double value3 = (double)lpBuffer.ullTotalPhys / 1073741824.0; double value4 = (double)(lpBuffer.ullTotalPhys - lpBuffer.ullAvailPhys) / 1073741824.0; uint dwMemoryLoad = lpBuffer.dwMemoryLoad; list.Add(new LauncherItem($"메모리: {value4:F1}GB / {value3:F1}GB ({dwMemoryLoad}% 사용)", $"사용 가능: {(double)lpBuffer.ullAvailPhys / 1073741824.0:F1}GB · Enter로 복사", null, $"메모리: {value4:F1}GB / {value3:F1}GB ({dwMemoryLoad}% 사용)", null, "\ue950")); } if (flag || text.Contains("disk") || text.Contains("디스크") || text.Contains("저장")) { DriveInfo[] drives = DriveInfo.GetDrives(); foreach (DriveInfo driveInfo in drives) { if (driveInfo.IsReady && driveInfo.DriveType == DriveType.Fixed) { double num2 = (double)driveInfo.TotalSize / 1073741824.0; double num3 = (double)driveInfo.AvailableFreeSpace / 1073741824.0; double num4 = num2 - num3; int value5 = (int)(num4 / num2 * 100.0); list.Add(new LauncherItem($"디스크 {driveInfo.Name.TrimEnd('\\')} {num4:F0}GB / {num2:F0}GB ({value5}%)", $"여유: {num3:F1}GB · {driveInfo.DriveFormat} · Enter로 복사", null, $"디스크 {driveInfo.Name}: {num4:F0}GB / {num2:F0}GB ({value5}%), 여유 {num3:F1}GB", null, "\ueda2")); } } } if (flag || text.Contains("uptime") || text.Contains("가동")) { TimeSpan timeSpan = TimeSpan.FromMilliseconds(Environment.TickCount64); string text2 = ((timeSpan.Days > 0) ? $"{timeSpan.Days}일 {timeSpan.Hours}시간 {timeSpan.Minutes}분" : $"{timeSpan.Hours}시간 {timeSpan.Minutes}분"); list.Add(new LauncherItem("가동 시간: " + text2, "마지막 재시작 이후 경과 · Enter로 복사", null, "가동 시간: " + text2, null, "\ue823")); } if (flag || text.Contains("top") || text.Contains("프로세스")) { try { IEnumerable values = Process.GetProcesses().Where(delegate(Process p) { try { return p.WorkingSet64 > 0; } catch { return false; } }).OrderByDescending(delegate(Process p) { try { return p.WorkingSet64; } catch { return 0L; } }) .Take(5) .Select(delegate(Process p) { try { return $"{p.ProcessName} ({p.WorkingSet64 / 1048576}MB)"; } catch { return p.ProcessName; } }); list.Add(new LauncherItem("메모리 상위 프로세스", string.Join(", ", values), null, "메모리 상위: " + string.Join(", ", values), null, "\ue7f4")); } catch { } } if (list.Count == 0) { list.Add(new LauncherItem("'" + text + "'에 해당하는 리소스 항목 없음", "cpu / mem / disk / uptime / top", null, null, null, "\ue7ba")); } return Task.FromResult((IEnumerable)list); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { object data = item.Data; string text = data as string; if (text != null && !string.IsNullOrWhiteSpace(text)) { try { Application current = Application.Current; if (current != null) { ((DispatcherObject)current).Dispatcher.Invoke((Action)delegate { Clipboard.SetText(text); }); } } catch { } } return Task.CompletedTask; } }