[英]How do I get the size (resolution) of all monitors in multi monitor setup
[英]How do I get the actual Monitor name? as seen in the resolution dialog
我正在嘗試為我的系統上的監視器獲取友好名稱。 我正在使用C#。
我試過Screen
, //./DisplayXX
給了我//./DisplayXX
。 我也嘗試過Win32_DesktopMonitor
和EnumDisplayDevices
,它們都給我//./DisplayXX
或Generic Monitor
的//./DisplayXX
,而我知道我的顯示名稱是SyncMaster
和SM2333T
。
現在,Windows知道這些監視器是什么,使用正確的名稱在“ 設備和打印機”窗口中顯示它們,並在用於設置位置和分辨率的對話框中顯示它們。
我在哪里可以從中獲取這些名稱? 我已經查看了注冊表,似乎無法找到它們,所以任何幫助都會很棒。
解決方案:我遇到的問題是第二次調用EnumDisplayDevices
時再次將iDevNum
設置為id,這意味着我試圖從錯誤的位置獲取數據,然后將其替換為0,它完美地工作,請參閱下面的碼。
var device = new DISPLAY_DEVICE();
device.cb = Marshal.SizeOf(device);
try
{
for (uint id = 0; EnumDisplayDevices(null, id, ref device, 0); id++)
{
Console.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}, {5}", id, device.DeviceName, device.DeviceString, device.StateFlags, device.DeviceID, device.DeviceKey));
Console.WriteLine();
device.cb = Marshal.SizeOf(device);
EnumDisplayDevices(device.DeviceName, 0, ref device, 0);
Console.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}, {5}", id, device.DeviceName, device.DeviceString, device.StateFlags, device.DeviceID, device.DeviceKey));
device.cb = Marshal.SizeOf(device);
device.cb = Marshal.SizeOf(device);
return;
}
}
}
catch (Exception ex)
{
Console.WriteLine(String.Format("{0}", ex.ToString()));
}
仔細檢查! 這就是你要找的,你現在可以編寫Screen.PrimaryScreen.DeviceFriendlyName()
並獲取監視器設備的真實名稱。
(是的,它與解決方案對話框中的名稱相同)
雖然我確實添加了一些個人觸摸來包裝這些代碼但我沒有創建它的Hard-Core部分,所以我要感謝2位開發人員,MS開發人員提供了C ++的基本知識,以及匿名開發人員翻譯了這些必需品到C#代碼。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Tools;
namespace ConsoleApplication35
{
internal class Program
{
private static void Main()
{
Console.WriteLine(Screen.PrimaryScreen.DeviceFriendlyName());
//output: ASUS MK241
Console.ReadLine();
}
}
}
namespace Tools
{
public static class ScreenInterrogatory
{
public const int ERROR_SUCCESS = 0;
#region enums
public enum QUERY_DEVICE_CONFIG_FLAGS : uint
{
QDC_ALL_PATHS = 0x00000001,
QDC_ONLY_ACTIVE_PATHS = 0x00000002,
QDC_DATABASE_CURRENT = 0x00000004
}
public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY : uint
{
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = 0xFFFFFFFF,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST = 15,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000,
DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_SCANLINE_ORDERING : uint
{
DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0,
DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3,
DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_ROTATION : uint
{
DISPLAYCONFIG_ROTATION_IDENTITY = 1,
DISPLAYCONFIG_ROTATION_ROTATE90 = 2,
DISPLAYCONFIG_ROTATION_ROTATE180 = 3,
DISPLAYCONFIG_ROTATION_ROTATE270 = 4,
DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_SCALING : uint
{
DISPLAYCONFIG_SCALING_IDENTITY = 1,
DISPLAYCONFIG_SCALING_CENTERED = 2,
DISPLAYCONFIG_SCALING_STRETCHED = 3,
DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4,
DISPLAYCONFIG_SCALING_CUSTOM = 5,
DISPLAYCONFIG_SCALING_PREFERRED = 128,
DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_PIXELFORMAT : uint
{
DISPLAYCONFIG_PIXELFORMAT_8BPP = 1,
DISPLAYCONFIG_PIXELFORMAT_16BPP = 2,
DISPLAYCONFIG_PIXELFORMAT_24BPP = 3,
DISPLAYCONFIG_PIXELFORMAT_32BPP = 4,
DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5,
DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff
}
public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint
{
DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
}
public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
{
DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3,
DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4,
DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5,
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6,
DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF
}
#endregion
#region structs
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_SOURCE_INFO
{
public LUID adapterId;
public uint id;
public uint modeInfoIdx;
public uint statusFlags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_TARGET_INFO
{
public LUID adapterId;
public uint id;
public uint modeInfoIdx;
private DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
private DISPLAYCONFIG_ROTATION rotation;
private DISPLAYCONFIG_SCALING scaling;
private DISPLAYCONFIG_RATIONAL refreshRate;
private DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
public bool targetAvailable;
public uint statusFlags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_RATIONAL
{
public uint Numerator;
public uint Denominator;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_PATH_INFO
{
public DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
public DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
public uint flags;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_2DREGION
{
public uint cx;
public uint cy;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
{
public ulong pixelRate;
public DISPLAYCONFIG_RATIONAL hSyncFreq;
public DISPLAYCONFIG_RATIONAL vSyncFreq;
public DISPLAYCONFIG_2DREGION activeSize;
public DISPLAYCONFIG_2DREGION totalSize;
public uint videoStandard;
public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_TARGET_MODE
{
public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTL
{
private int x;
private int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_SOURCE_MODE
{
public uint width;
public uint height;
public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
public POINTL position;
}
[StructLayout(LayoutKind.Explicit)]
public struct DISPLAYCONFIG_MODE_INFO_UNION
{
[FieldOffset(0)]
public DISPLAYCONFIG_TARGET_MODE targetMode;
[FieldOffset(0)]
public DISPLAYCONFIG_SOURCE_MODE sourceMode;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_MODE_INFO
{
public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
public uint id;
public LUID adapterId;
public DISPLAYCONFIG_MODE_INFO_UNION modeInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
{
public uint value;
}
[StructLayout(LayoutKind.Sequential)]
public struct DISPLAYCONFIG_DEVICE_INFO_HEADER
{
public DISPLAYCONFIG_DEVICE_INFO_TYPE type;
public uint size;
public LUID adapterId;
public uint id;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPLAYCONFIG_TARGET_DEVICE_NAME
{
public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
public ushort edidManufactureId;
public ushort edidProductCodeId;
public uint connectorInstance;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string monitorFriendlyDeviceName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string monitorDevicePath;
}
#endregion
#region DLL-Imports
[DllImport("user32.dll")]
public static extern int GetDisplayConfigBufferSizes(
QUERY_DEVICE_CONFIG_FLAGS flags, out uint numPathArrayElements, out uint numModeInfoArrayElements);
[DllImport("user32.dll")]
public static extern int QueryDisplayConfig(
QUERY_DEVICE_CONFIG_FLAGS flags,
ref uint numPathArrayElements, [Out] DISPLAYCONFIG_PATH_INFO[] PathInfoArray,
ref uint numModeInfoArrayElements, [Out] DISPLAYCONFIG_MODE_INFO[] ModeInfoArray,
IntPtr currentTopologyId
);
[DllImport("user32.dll")]
public static extern int DisplayConfigGetDeviceInfo(ref DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName);
#endregion
private static string MonitorFriendlyName(LUID adapterId, uint targetId)
{
var deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME
{
header =
{
size = (uint)Marshal.SizeOf(typeof (DISPLAYCONFIG_TARGET_DEVICE_NAME)),
adapterId = adapterId,
id = targetId,
type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME
}
};
var error = DisplayConfigGetDeviceInfo(ref deviceName);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
return deviceName.monitorFriendlyDeviceName;
}
private static IEnumerable<string> GetAllMonitorsFriendlyNames()
{
uint pathCount, modeCount;
var error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS, out pathCount, out modeCount);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
var displayPaths = new DISPLAYCONFIG_PATH_INFO[pathCount];
var displayModes = new DISPLAYCONFIG_MODE_INFO[modeCount];
error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
ref pathCount, displayPaths, ref modeCount, displayModes, IntPtr.Zero);
if (error != ERROR_SUCCESS)
throw new Win32Exception(error);
for (var i = 0; i < modeCount; i++)
if (displayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
yield return MonitorFriendlyName(displayModes[i].adapterId, displayModes[i].id);
}
public static string DeviceFriendlyName(this Screen screen)
{
var allFriendlyNames = GetAllMonitorsFriendlyNames();
for (var index = 0; index < Screen.AllScreens.Length; index++)
if (Equals(screen, Screen.AllScreens[index]))
return allFriendlyNames.ToArray()[index];
return null;
}
}
}
在從EnumDisplayDevices
獲得類似//./DisplayX
的DisplayDevice.DeviceName
之后,你應該第二次調用'EnumDisplayDevices',這次提供你從前一個調用獲得的'DisplayDevice.DeviceName'作為lpDevice
,'0 '作為iDevNum
。 然后,您將在DisplayDevice.DeviceString
擁有監視器名稱。
幾乎可以通過SetupAPI函數系列獲得此信息。 我不記得我頭腦中的具體細節,但您需要獲取所有監視器設備(GUID_DEVINTERFACE_MONITOR)並獲取其友好名稱(SPDRP_FRIENDLYNAME)。
從這里: 獲取精確的監視器/顯示/屏幕名稱
好吧,這個問題很老,但是,為了谷歌重定向,我建議我的'WindowsDisplayAPI'庫。
https://www.nuget.org/packages/WindowsDisplayAPI
使用該庫,有多種方法可以獲取顯示名稱。 最簡單的方法是:
foreach (var display in Display.GetDisplays())
{
Console.WriteLine(display.DeviceName);
}
但這是使用舊的API,如果您確定您的程序至少針對Windows Vista,我建議使用以下代碼:
foreach (var target in DisplayConfig.PathDisplayTarget.GetDisplayTargets())
{
Console.WriteLine(target.FriendlyName);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.