From caa7436d5180c6373f6176b7a9da26804a89d9c6 Mon Sep 17 00:00:00 2001 From: sothman01 Date: Mon, 28 Apr 2025 13:42:16 +0800 Subject: [PATCH] Add GPU detection and usage retrieval with error handling --- NvmlWrapper.cs | 9 +++++ Worker.cs | 95 ++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 85 insertions(+), 19 deletions(-) diff --git a/NvmlWrapper.cs b/NvmlWrapper.cs index 7ebdd45..e32719b 100644 --- a/NvmlWrapper.cs +++ b/NvmlWrapper.cs @@ -9,6 +9,15 @@ public static class NvmlWrapper [DllImport("nvml.dll", EntryPoint = "nvmlShutdown")] public static extern int NvmlShutdown(); + // Get device count + [DllImport("nvml.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int nvmlDeviceGetCount_v2(ref uint deviceCount); + + public static int NvmlDeviceGetCount(ref uint deviceCount) + { + return nvmlDeviceGetCount_v2(ref deviceCount); + } + [DllImport("nvml.dll", EntryPoint = "nvmlDeviceGetHandleByIndex_v2")] public static extern int NvmlDeviceGetHandleByIndex(int index, out IntPtr device); diff --git a/Worker.cs b/Worker.cs index 2fa0983..70114ee 100644 --- a/Worker.cs +++ b/Worker.cs @@ -190,26 +190,83 @@ namespace ResourceMonitorService 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 + if (!IsNvidiaGpuPresent()) { - Usage = utilization.Gpu, - Temperature = temperature, - FanSpeed = fanSpeed - }; + return new + { + Usage = 0, + Temperature = 0, + FanSpeed = 0, + IsAvailable = false, + Message = "No NVIDIA GPU detected" + }; + } + + try + { + + 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 + }; + } + catch (Exception ex) + { + return new + { + Usage = 0, + Temperature = 0, + FanSpeed = 0, + IsAvailable = false, + Error = ex.Message + }; + } + } + + private bool IsNvidiaGpuPresent() + { + try + { + // Method 1: Try to initialize NVML + NvmlWrapper.NvmlInit(); + uint deviceCount = 0; + NvmlWrapper.NvmlDeviceGetCount(ref deviceCount); + NvmlWrapper.NvmlShutdown(); + + return deviceCount > 0; + } + catch + { + // Method 2: Fallback to checking using WMI + try + { + using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController WHERE Name LIKE '%NVIDIA%'")) + { + var collection = searcher.Get(); + return collection.Count > 0; + } + } + catch + { + return false; + } + } } private object GetCurrentlyRunningGame()