6

My C# application sits on the embedded box which has Intel motherboard and graphics chipset. ATI graphics card is put on to PCI express. Generally graphics card drives the video, but if ATI card fails then the video comes out from graphics chipset.

I have to detect the failure of ATI graphics card for diagnostic purposes.

Any ideas/sample code on how to do this.

Thanks in advance Raju

Town
  • 14,706
  • 3
  • 48
  • 72
user209293
  • 889
  • 3
  • 18
  • 27
  • 12
    What have you tried? Here we like to see an effort, or at least some research so that we don't give you answers that you've already tried, as well as showing some dedication to helping you help yourself. – Bob G May 13 '11 at 12:57

6 Answers6

21

This should hopefully get you started.

Add a reference to System.Management, then you can do this:

ManagementObjectSearcher searcher 
     = new ManagementObjectSearcher("SELECT * FROM Win32_DisplayConfiguration");

    string graphicsCard = string.Empty;
    foreach (ManagementObject mo in searcher.Get())
    {
        foreach (PropertyData property in mo.Properties)
        {
           if (property.Name == "Description")
           {
               graphicsCard = property.Value.ToString();
           }
        }
    }

In my case, graphicsCard is equal to

NVIDIA GeForce 8400 GS (Microsoft Corporation - WDDM v1.1)

Town
  • 14,706
  • 3
  • 48
  • 72
  • I tried the same but I am not getting the WDDM version – Richa Garg Sep 02 '16 at 11:59
  • This gives a wrong device on my *Windows 10 (RS2) + Intel(R) HD Graphics 4600 + NVIDIA GeForce GTX 1080* system, my monitors are plugged on GTX1080 but this gives HD4600. However, I find the `Win32_DisplayControllerConfiguration` class gives correct answer. – hillin May 23 '17 at 02:48
  • Very nice. Is there a reference somewhere what you can query apart from Win32_DisplayConfiguration? – WhoAmI Mar 27 '19 at 21:34
  • hillin - does it find multiple devices but your HD Graphics happens to be last? This code does not seem to recognize the case of multiple graphics cards – DAG Jul 30 '20 at 15:14
14

I'm not a fan of how the selected answer only returns the first video controller. Also, there's no need to loop over all the properties. Just get the ones you need. If CurrentBitsPerPixel is not null, then you're looking at one of the active controllers. I'm using Win32_VideoController as suggested by @bairog, instead of the deprecated Win32_DisplayConfiguration.

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 (currentBitsPerPixel.Value != null)
            System.Console.WriteLine(description.Value);
    }
}

My machine has 3 video controllers. The first one is not active (ShoreTel). The second one is active, but is not the video card (Desktop Authority). The third one is my NVidia. This code will print out both the DA controller and the NVidia controller.

NielW
  • 3,626
  • 1
  • 30
  • 38
  • 1
    Technically, the accepted answer only returns the description of the *last* ManagementObject it encounters with a Description field, since it doesn't break after it finds the first one. Either way, good detection code should handle the case where there's more than one display, or even more than one GPU, available. – Dan Bechard Sep 24 '18 at 23:12
  • 1
    This answer picks up ALL active graphics cards, that can mean the integrated CPU graphics + the actual graphics card used for video. If you need the main GPU neither of the answers here give a suitable solution. – Dan Hall Jun 21 '19 at 14:21
  • This answer is wrong among other things because it will also pick RDP display adapter because it also has `currentBitsPerPixel` set. – Igor Levicki Aug 18 '19 at 14:33
2

Promoted answer works only for single video card system. When I have ATI and Nvidia cards - WMI query returns ATI even if that monitor is plugged into Nvidia card, dxdiag shows Nvidia and games runs on that card (usage).

The only way I could determine right video card was using SlimDX to create DX device and examine what card it used. However that .dll weights over 3Mb.

var graphicsCardName = new Direct3D().Adapters[0].Details.Description;
  • 4
    Try `SELECT * FROM Win32_VideoController` query instead. Currently active card can be determined by **CurrentBitsPerPixel** or **CurrentHorizontalResolution** value not equals null. Worked for me on a laptop with Intel HD 3000 + Ati Radeon HD 6470M. Complete list of WMI keys I've found [**in this CodeProject article**](http://www.codeproject.com/Articles/17973/How-To-Get-Hardware-Information-CPU-ID-MainBoard-I) – bairog Jan 27 '14 at 06:09
  • @bairog ^^This should be the answer. – NielW Apr 23 '14 at 22:07
  • 3
    @bairog not true on my *Windows 10 (RS2) + Intel(R) HD Graphics 4600 + NVIDIA GeForce GTX 1080* system, both devices have non-null **CurrentBitsPerPixel** and **CurrentHorizontalResolution** values. – hillin May 23 '17 at 02:45
1

Your question isn't entirely clear, so I'm not sure if the follwing idea will help or not.

Perhaps something very simple would suffice:

If the two graphics cards run different resolutions check the monitor resolution using:

System.Windows.Forms.SystemInformation.PrimaryMonitorSize

Similarly, if one card supports more than one monitor, check the number of monitors using SystemInformation.MonitorCount.

Ben Schwehn
  • 4,505
  • 1
  • 27
  • 45
0

I tried all the approaches in this question but none gives me a correct answer. However I found it possible to get your current using the Win32_DisplayControllerConfiguration class. Although according to MSDN this class is obsolete, it's the only one returning a correct answer:

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root\\CIMV2", 
                    "SELECT * FROM Win32_DisplayControllerConfiguration"); 

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------    ");
                    Console.WriteLine("Win32_DisplayControllerConfiguration instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
            }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}

(Code generated by WMI Code Creator, a great tool if you are messing with WMI.)

This gives GeForce GTX 1080 on my Windows 10 (RS2) + Intel(R) HD Graphics 4600 + NVIDIA GeForce GTX 1080 system.

hillin
  • 1,603
  • 15
  • 21
  • This gives you very little information regarding the card, that's the reason it's obsolete. Your're right though that none of the answers give the correct result. On many systems, the onboard GPU is active (currentBitsPerPixel ! null) along with the main GPU. – Dan Hall Jun 21 '19 at 14:19
0

Sometimes I need to switch between the Nvidia GPU and onboard GPU. To know which is connected to the monitor, I use the property MinRefreshRate. It works reliably for me, not CurrentBitsPerPixel.

public static void UpdateActiveGpu()
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
        foreach (ManagementObject mo in searcher.Get())
        {
            PropertyData minRefreshRate = mo.Properties["MinRefreshRate"];
            PropertyData description = mo.Properties["Description"];

            if (minRefreshRate != null && description != null && minRefreshRate.Value != null)
            {
                Global.Instance.activeGpu = description.Value.ToString();
                break;
            }
        }
    }
jrw
  • 65
  • 1
  • 8