简体   繁体   English

如何获取实际的Monitor名称? 如解决方案对话框中所示

[英]How do I get the actual Monitor name? as seen in the resolution dialog

I am trying to grab the friendly name for the monitors on my system. 我正在尝试为我的系统上的监视器获取友好名称。 I am using C#. 我正在使用C#。

I have tried Screen , which just gives me //./DisplayXX . 我试过Screen//./DisplayXX给了我//./DisplayXX I have also tried both Win32_DesktopMonitor and EnumDisplayDevices , they all give me variations of //./DisplayXX OR Generic Monitor , whereas I know my displays names are SyncMaster and SM2333T . 我也尝试过Win32_DesktopMonitorEnumDisplayDevices ,它们都给我//./DisplayXXGeneric Monitor//./DisplayXX ,而我知道我的显示名称是SyncMasterSM2333T

Now Windows knows what these monitors are, displays them in the Devices and Printers windows with the correct names, and also in the dialog for setting location and resolution. 现在,Windows知道这些监视器是什么,使用正确的名称在“ 设备和打印机”窗口中显示它们,并在用于设置位置和分辨率的对话框中显示它们。

Where can I grab these names from? 我在哪里可以从中获取这些名称? I have looked in the registry and cant seem to find them, so any help will be great. 我已经查看了注册表,似乎无法找到它们,所以任何帮助都会很棒。

SOLUTION: The issue I had was when calling EnumDisplayDevices the second time I was setting iDevNum to id again, which meant I was trying to grab data from the wrong place, I then replaced this with 0, and it works perfectly, see below for the code. 解决方案:我遇到的问题是第二次调用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()));
    }

Examine carefully! 仔细检查! this is what you looking for, you can now write Screen.PrimaryScreen.DeviceFriendlyName() and get the real name of the monitor device. 这就是你要找的,你现在可以编写Screen.PrimaryScreen.DeviceFriendlyName()并获取监视器设备的真实名称。
(and yes, it is the same name seen in resolution dialog) (是的,它与解决方案对话框中的名称相同)

While I did add some personal touch to wrap this code I did not create the Hard-Core part of it, And so I would like to thank 2 developers, The MS developer who gave the essentials in C++ and the anonymous developer who translated those essentials to C# code. 虽然我确实添加了一些个人触摸来包装这些代码但我没有创建它的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;
        }

    }

}

After you get a DisplayDevice.DeviceName like //./DisplayX from EnumDisplayDevices , you are supposed to call 'EnumDisplayDevices' a second time, this time providing the 'DisplayDevice.DeviceName' that you got from the previous call as lpDevice , and '0' as iDevNum . 在从EnumDisplayDevices获得类似//./DisplayXDisplayDevice.DeviceName之后,你应该第二次调用'EnumDisplayDevices',这次提供你从前一个调用获得的'DisplayDevice.DeviceName'作为lpDevice ,'0 '作为iDevNum Then you'll have the monitor name in DisplayDevice.DeviceString . 然后,您将在DisplayDevice.DeviceString拥有监视器名称。

This information is almost certainly obtained through the SetupAPI family of functions. 几乎可以通过SetupAPI函数系列获得此信息。 I don't recall the specifics off the top of my head, but you will need to get all monitor devices (GUID_DEVINTERFACE_MONITOR) and obtain their friendly names (SPDRP_FRIENDLYNAME). 我不记得我头脑中的具体细节,但您需要获取所有监视器设备(GUID_DEVINTERFACE_MONITOR)并获取其友好名称(SPDRP_FRIENDLYNAME)。

From here: Get Exact Monitor/Display/Screen Name 从这里: 获取精确的监视器/显示/屏幕名称

Well, this question is old, however, as for the sake of google redirects, I suggest my 'WindowsDisplayAPI' library. 好吧,这个问题很老,但是,为了谷歌重定向,我建议我的'WindowsDisplayAPI'库。

https://www.nuget.org/packages/WindowsDisplayAPI https://www.nuget.org/packages/WindowsDisplayAPI


Using the library, there are multiple ways to get the display name. 使用该库,有多种方法可以获取显示名称。 The simplest way is: 最简单的方法是:

foreach (var display in Display.GetDisplays())
{
    Console.WriteLine(display.DeviceName);
}

But this is using the old API, if you are sure that your program targets at least Windows Vista, I suggest the following code: 但这是使用旧的API,如果您确定您的程序至少针对Windows Vista,我建议使用以下代码:

foreach (var target in DisplayConfig.PathDisplayTarget.GetDisplayTargets())
{
    Console.WriteLine(target.FriendlyName);
}

I have been seraching for an answer to this same question. 我一直在搜索这个问题的答案。 In this link it is mentioned that generic pnp monitor is shown, because there is no driver installed for the monitor and the device is running with the Generic PnP Monitor Driver. 此链接中 ,提到了通用pnp监视器,因为没有为监视器安装驱动程序,并且设备正在使用Generic PnP Monitor Driver运行。

For windows 7 and higher there seems to be a different function than EnumDisplayDevices to get the desired display names as shown in the control panel. 对于Windows 7及更高版本,似乎与EnumDisplayDevices具有不同的功能,以获得所需的显示名称,如控制面板中所示。 This can be done with the DisplayConfigGetDeviceInfo function as explained here . 这可以通过DisplayConfigGetDeviceInfo函数来完成作为解释在这里 I hope someone soon can translate this to Delphi, which I am looking for. 我希望很快能有人将其翻译成我正在寻找的Delphi。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM