C#如何有效检测程序当前实际使用的显卡设备
参考相关帖子后,我需要检测程序实际正在使用的显卡。为了确保程序使用NVIDIA独立显卡而非Intel集成显卡,我做了以下配置:
- 将NVIDIA显卡设置为全局默认使用设备

- 为我的应用单独强制指定使用NVIDIA显卡

因此我可以确定我的程序正在使用NVIDIA显卡,同时我也在任务管理器中看到了对应GPU的占用。
即便如此,我仍然需要通过代码的方式确认程序正在使用NVIDIA而非Intel显卡。我从相关页面找到了一个实现方案,我的代码如下:
string strGraphicCards = "Graphic cards: "; ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController"); foreach (ManagementObject mo in searcher.Get()) { PropertyData currentBitsPerPixel = mo.Properties["CurrentBitsPerPixel"]; PropertyData description = mo.Properties["Description"]; if (currentBitsPerPixel != null && description != null) { if (mo["CurrentBitsPerPixel"] != null && mo["CurrentHorizontalResolution"] != null) strGraphicCards += " **USED** " + description.Value + ", "; else strGraphicCards += description.Value + ", "; } } Serializers.Loggers.WriteNLog(strGraphicCards, eLogLevel.Trace);
但运行后得到的结果和预期不符:
希望大家能帮忙解答问题出在哪里,感谢。
Patrick
问题原因
你使用的WMI判断逻辑存在维度偏差:Win32_VideoController 下的 CurrentBitsPerPixel、CurrentHorizontalResolution 等属性,统计的是系统层面负责输出显示画面到显示器的显卡,和单个进程实际使用的计算/渲染显卡没有直接关联。如果你的显示器插在Intel集成显卡的输出接口上,哪怕你给程序单独指定了用NVIDIA独立显卡运行,这两个属性也只会给Intel核显标记为USED,自然和预期结果不符。
解决方案
推荐使用DirectX API获取当前进程实际绑定的渲染设备,该逻辑和系统显卡调度规则完全对齐,返回结果准确:
- 首先安装NuGet包
SharpDX.Direct3D11 - 参考代码如下:
using SharpDX.Direct3D11; using SharpDX.DXGI; public static string GetCurrentProcessUsedGpu() { using var factory = new Factory1(); // 创建默认硬件D3D设备,对应的适配器即为程序实际使用的显卡 using var device = new Device(DriverType.Hardware, DeviceCreationFlags.None); using var adapter = device.Adapter; return adapter.Description1.Description.Trim(); } // 调用示例 var usedGpu = GetCurrentProcessUsedGpu(); Serializers.Loggers.WriteNLog($"当前程序使用显卡:{usedGpu}", eLogLevel.Trace);
如果仅需要适配NVIDIA显卡场景,也可以调用NVIDIA官方NvAPI判断当前进程是否挂载NVIDIA驱动,不过适用性弱于上述通用方案。
补充说明
原WMI方案仅适合判断系统当前有哪些显卡在承担显示输出工作,完全不适合判断单个进程的显卡使用情况。任务管理器中的GPU占用是按进程维度统计的,和WMI的全局统计维度本身存在差异,两者结果不一致属于正常现象。
内容的提问来源于stack exchange,提问作者Patrick

