views:

317

answers:

2

I am trying to count the number of monitors attached to a machine ( not virtual displays, so two monitors running with clone would have one virtual display but two physical monitors ). I am currently counting the active monitors listed under the device manager. This works fine in Windows Vista and 7, but it seems that in Windows XP, there are occasionally phantom monitors that don't exist, seemingly caused by drivers of sorts.

When I had conflicting nVidia and ATI drivers on a single machine with two video adapters, I ended up getting 4 monitors listed even when only one was real. Phantom monitors could be deleted but would reappear when a real monitor was attached or detatched or if you tried to search for new hardware.

Also, laptops with drivers for a laptop dock would sometimes have anywhere from 1 to 7 extra phantom monitors even though the dock only added one extra monitor.

Is there another way to reliably count physical monitors? If not, does anyone know to reliably filter out the phantom monitors in XP?

+4  A: 

I would say try WMI. WMI has classes that wrap all kinds of physical things that deal with your machine. I looked around and:

Win32_DesktopMonitor
http://msdn.microsoft.com/en-us/library/aa394122%28VS.85%29.aspx

Seems to be what you would use. A basic WQL query for that would be:

SELECT * FROM Win32_DesktopMonitor

That would work for above XP. As for XP specifically, you would want:

Win32_DisplayConfiguration
http://msdn.microsoft.com/en-us/library/aa394137%28VS.85%29.aspx

On XP boxes you can query WMI through VBScript, and on later OSs you can use PowerShell (gwmi).

NOTE
You can use the incredibly useful wbemtest to test your WQL queries. Should be found by the run prompt (Start > Run > wbemtest).

Good luck!

asteroid
Thanks for the answer! WMI seems to work perfectly. I will test with a few more machines to ensure that it will suit my needs. Just curious, what are the performance implications of using WMI ( I'll try to learn a bit more about it, currently not taht familiaor with it )? An answer relative to the cost of using the device manager would be helpful enough ( which I believe boils down to a few API calls that do some registry reads )
chromic
Locally, a little slower would be my rough guess, but not by much. If you are doing remote calls...slow. Try to avoid querying sets of results that you can pare down with better statements (i.e. avoid SELECT * if possible).This blog post <a href="http://blogs.msdn.com/wmi/archive/2009/06/27/wmi-improving-your-wmi-application-performance-in-fan-out-scenario.aspx /> _might_ be helpful depending on how you are going to implement it. I got that from this <a href="http://stackoverflow.com/questions/1045782/how-can-i-improve-wmi-performance-in-net /> on SO.
asteroid
After some testing it seems the WMI is not a perfect solution after all. For many of my machines, it likes to return 2 monitors, even though one had 3 and one was a laptop with nothing attached.
chromic
+2  A: 

GetSystemMetrics(SM_CMONITORS) might be what you're looking for.

http://msdn.microsoft.com/en-us/library/ms724385%28VS.85%29.aspx

If you want to interrogate the monitors and display devices further, try these functions:

http://msdn.microsoft.com/en-us/library/dd145072%28VS.85%29.aspx

PhilMY
Unfortunately, I have already tried these function and all they do is return the number of virtual displays. If a person is currently running multiple monitors but have it set to Clone/Duplicate the same image on all screens, GetSystemMetrics returns 1.
chromic