using System.Diagnostics; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using Microsoft.AspNetCore.Http; using System.Runtime.InteropServices; using System.Management; namespace ResourceMonitorService { public class Worker : BackgroundService { private readonly IHostApplicationLifetime _lifetime; public Worker(IHostApplicationLifetime lifetime) { _lifetime = lifetime; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var builder = WebApplication.CreateBuilder(); builder.Services.AddControllers().AddNewtonsoftJson(); var app = builder.Build(); app.MapGet("/api/resource-usage", async context => { var currentTime = GetCurrentTime(); var computerInfo = GetComputerInfo(); var cpuUsage = GetCpuUsage(); var ramUsage = GetRamUsage(); var gpuUsage = GetGpuUsage(); var runningGame = GetCurrentlyRunningGame(); var resourceUsage = new { CurrentTime = currentTime, ComputerInfo = computerInfo, CPU = cpuUsage, RAM = ramUsage, GPU = gpuUsage, CurrentlyRunningGame = runningGame }; var json = JsonConvert.SerializeObject(resourceUsage); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(json); }); app.RunAsync(stoppingToken); await Task.Delay(Timeout.Infinite, stoppingToken); } private object GetComputerInfo() { return new { MachineName = Environment.MachineName, OSVersion = RuntimeInformation.OSDescription, OSArchitecture = RuntimeInformation.OSArchitecture.ToString(), ProcessorCount = Environment.ProcessorCount }; } private object GetCpuUsage() { var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); cpuCounter.NextValue(); Thread.Sleep(1000); // Wait a second to get a valid reading var usage = cpuCounter.NextValue(); if (usage > 80) { // Get the current processes and sort them by CPU usage in descending order var processes = Process.GetProcesses().OrderByDescending(p => p.TotalProcessorTime); // Create a new anonymous type containing the CPU usage, RAM usage, and the top 3 highest CPU-using processes return new { Usage = usage, Process1 = new { Name = processes.ElementAt(0).ProcessName, TotalProcessorTime = processes.ElementAt(0).TotalProcessorTime, WorkingSet64 = processes.ElementAt(0).WorkingSet64 / (1024 * 1024) // Convert to MB }, Process2 = new { Name = processes.ElementAt(1).ProcessName, TotalProcessorTime = processes.ElementAt(1).TotalProcessorTime, WorkingSet64 = processes.ElementAt(1).WorkingSet64 / (1024 * 1024) // Convert to MB }, Process3 = new { Name = processes.ElementAt(2).ProcessName, TotalProcessorTime = processes.ElementAt(2).TotalProcessorTime, WorkingSet64 = processes.ElementAt(2).WorkingSet64 / (1024 * 1024) // Convert to MB } }; } return new { Usage = usage }; } private float GetRamUsage() { var ramCounter = new PerformanceCounter("Memory", "Available MBytes"); var totalMemory = GetTotalPhysicalMemory(); var availableMemory = ramCounter.NextValue() * 1024 * 1024; return (float)(totalMemory - availableMemory) / totalMemory * 100; } private ulong GetTotalPhysicalMemory() { ulong totalMemory = 0; var searcher = new ManagementObjectSearcher("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem"); foreach (var obj in searcher.Get()) { totalMemory = (ulong)obj["TotalPhysicalMemory"]; } return totalMemory; } private object GetGpuUsage() { NvmlWrapper.NvmlInit(); IntPtr device; NvmlWrapper.NvmlDeviceGetHandleByIndex(0, out device); NvmlWrapper.NvmlUtilization utilization; NvmlWrapper.NvmlDeviceGetUtilizationRates(device, out utilization); uint temperature; NvmlWrapper.NvmlDeviceGetTemperature(device, 0, out temperature); uint fanSpeed; NvmlWrapper.NvmlDeviceGetFanSpeed(device, out fanSpeed); NvmlWrapper.NvmlShutdown(); return new { Usage = utilization.Gpu, Temperature = temperature, FanSpeed = fanSpeed }; } private object GetCurrentlyRunningGame() { var processes = Process.GetProcesses(); foreach (var process in processes) { try { var filePath = process.MainModule.FileName; if (filePath.Contains(@"\steamapps\common\")) { // Extract the game directory name var parts = filePath.Split(new[] { @"\steamapps\common\" }, StringSplitOptions.None); if (parts.Length > 1) { var gamePath = parts[1]; var gameName = gamePath.Split(Path.DirectorySeparatorChar)[0]; return new { GameName = gameName, ExecutableName = Path.GetFileName(filePath), FullPath = filePath, ProcessId = process.Id, MemoryUsage = process.WorkingSet64 / (1024 * 1024) + " MB", // Memory usage in MB CpuTime = process.TotalProcessorTime.ToString(), StartTime = process.StartTime.ToString("G"), // General date/time pattern UserName = Environment.UserName // The user running the process }; } } } catch (Exception) { // Handle access exceptions or continue if not important } } return "No Steam game is currently running."; } private string GetCurrentTime() { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } } }