Tuesday, March 2, 2010

Using WMI to Query Monitor Information

I recently had a need to programmatically determine the number, make, and model of each monitor attached to a Windows computer system. Knowing that WMI provides a bewildering array of such functionality, I started here with the WMI Win32_DesktopMonitor class.

image Figure 1: Win32_DesktopMonitor WMI class description.

As you can see in figure 1, the information I needed is supplied by this class. I coded up a quick C# application that used this WMI class to report the monitors and thought that I was done. The problem is that each run of the program only ever showed one monitor on my system. I pulled up PythonWin and using Tim Golden's excellent WMI Python module I confirmed that WMI provides only one monitor. Searching the Internet told me that I was not the first to have this problem and in fact on Windows Vista and up (I was running on Windows 7) the Win32_DesktopMonitor class only returns one monitor in many cases. The issues has something to do with the video driver changes that were introduced in Windows Vista and improved in Windows 7. Most people that encountered this problem dropped into the Win32 C API to solve the issue. I still had hope for WMI, after all Windows knows how many monitors I have and what kind they are. Once again I used Tim Golden’s WMI Python module to poke around with various WMI classes and I found the Win32_PnPEntity class.

image Figure 2: Win32_PnPEntity WMI class description.

I did a quick query to dump all of these out to see if I could use this WMI class.

import wmi
obj = wmi.WMI().Win32_PnPEntity(ConfigManagerErrorCode=0)

The ConfigManagerErrorCode=0 parameter means that I want all devices that are working properly. Looking at my obj variable, there was a ton of data but I noticed some devices with the string “DISPLAY\\…” within it. Here is some of the output:

image

I quickly filtered my output in Python with this:


displays = [x for x in obj if 'DISPLAY' in str(x)]
for item in displays:
print item

And this is the result:

image

This was the result that I was looking for. I have two Dell E248WFP monitors and finally WMI agreed with me. Every property is exactly the same except for the DeviceID because this is what PnP uses to distinguish between the two monitors.

I quickly re-coded my C# function to use the WMI class Win32_PnPEntity. I did make a change however. The C# version filters devices where the Service = ‘monitor’ rather than looking for ‘DISPLAY’ in the DeviceID.

Special Thanks to Tim Golden who makes WMI enjoyable in Python!

3 comments:

  1. will it work to show connected monitors with a VGA Splitter? Or show only 1 monitor again when i have 10 attached to splitter

    ReplyDelete
    Replies
    1. If you are using an external VGA splitter there is nothing can be done since your o/s cannot sense it at first place.

      Delete
  2. Good thinking going to PNP Devices. Thanks for this post.

    ReplyDelete