【发布时间】:2019-01-17 03:18:10
【问题描述】:
我有一个 Windows 应用程序需要在运行时检测正确数量的连接监视器。
到目前为止,我在互联网和 Stack Overflow 上找到的所有方法都失败了。无论屏幕是否实际连接,它们都返回 1。并且当连接2个屏幕时,其中一些正确返回2,但是,当没有连接屏幕时,它们都不返回0。我需要它在没有连接屏幕时返回 0。
即使是检测屏幕是否连接的方法也可以工作。
下面是我尝试过的6种方法的代码列表。
int numberOfScreens = 0;
numberOfScreens = Screen.AllScreens.Length; //1 DOESN'T WORK
numberOfScreens = SystemInformation.MonitorCount; //2 DOESN'T WORK
numberOfScreens = GetSystemMetrics(80); //3 DOESN'T WORK
/*4 DOESN'T WORK
* //This code was outside of the function
* [DllImport("user32")]
* private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lpRect, MonitorEnumProc callback, int dwData);
* private delegate bool MonitorEnumProc(IntPtr hDesktop, IntPtr hdc, ref Rect pRect, int dwData);
* [StructLayout(LayoutKind.Sequential)]
* private struct Rect {
* public int left;
* public int top;
* public int right;
* public int bottom;
* }
*/
int monCount = 0;
Rect r = new Rect();
MonitorEnumProc callback = (IntPtr hDesktop, IntPtr hdc, ref Rect prect, int d) => ++monCount > 0;
if (EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, callback, 0)) {
Console.WriteLine("You have {0} monitors", monCount);
numberOfScreens = monCount;
} else {
Console.WriteLine("An error occured while enumerating monitors");
}
//5 DOESN'T WORK
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PnPEntity where service =\"monitor\"");
numberOfScreens = searcher.Get().Count;
//6 DOESN'T WORK
var active = true;
var query = "select * from WmiMonitorBasicDisplayParams";
using (var wmiSearcher = new ManagementObjectSearcher("\\root\\wmi", query)) {
var results = wmiSearcher.Get();
foreach (ManagementObject wmiObj in results) {
// get the "Active" property and cast to a boolean, which should
// tell us if the display is active. I've interpreted this to mean "on"
active = (Boolean)wmiObj["Active"];
}
}
Console.WriteLine(active);
如果有任何其他可靠的方法来检测正确的显示器数量,我将不胜感激。
谢谢!
附带说明,在 Default_Monitor 的注册表中设置了 EDID_OVERRIDE,因此无论发生什么,EDID 都不会改变。这不是我能改变的。但这可能是 Windows 说有监视器而实际上没有监视器的原因。这意味着它不会根据实际连接的显示器数量来计算显示器,而是根据它认为正在渲染到的显示器数量来计算。
鉴于这种怀疑,有没有一种方法可以检测实际连接的显示器数量?例如,插入了多少 HDMI/DVI/VGA 电缆,而不是 Windows 认为它要渲染到多少屏幕?
【问题讨论】:
-
好问题顺便说一句。我已经用尽了我的测试和谷歌搜索。我会开始抓取有关显示器和适配器的所有 winapi 资料,然后开始编写一些东西来循环并打印出来。
-
@TheSoftwareJedi - 其中一种方法确实使用了 winapi,特别是 EnumDisplayMonitors 函数:docs.microsoft.com/en-us/windows/desktop/api/winuser/… - 但是,在 api 中搞乱一点可能会给我一些有用的结果,但我不是充满希望。
标签: c# .net windows visual-studio