C# 检测连接的监视器';通过Win32_DesktopMonitor实现的s串行

C# 检测连接的监视器';通过Win32_DesktopMonitor实现的s串行,c#,multiple-monitors,C#,Multiple Monitors,我为一个问题挣扎了一段时间 我正在尝试获取所有连接的监视器的序列号 我已经尝试过Win32_DesktopMonitor,甚至CIM_DesktopMonitor,但都没有成功 例如,我连接了10台电视并正在运行,但这些电话只返回其中的4台。(见下面的屏幕截图) 我最好的猜测是关于WDDM,但如何绕过这个问题?尝试另一种方法,例如本机winapi函数。示例代码: public class Program { private static void Main(string[] args)

我为一个问题挣扎了一段时间

我正在尝试获取所有连接的监视器的序列号

我已经尝试过Win32_DesktopMonitor,甚至CIM_DesktopMonitor,但都没有成功

例如,我连接了10台电视并正在运行,但这些电话只返回其中的4台。(见下面的屏幕截图)


我最好的猜测是关于WDDM,但如何绕过这个问题?

尝试另一种方法,例如本机winapi函数。示例代码:

public class Program {
    private static void Main(string[] args) {
        var dd = new DISPLAY_DEVICE();
        dd.cb = Marshal.SizeOf(dd);
        uint devNum = 0;
        while (EnumDisplayDevices(null, devNum, ref dd, 0)) {
            uint devMon = 0;
            var ddMon = new DISPLAY_DEVICE();
            ddMon.cb = Marshal.SizeOf(ddMon);
            while (EnumDisplayDevices(dd.DeviceName, devMon, ref ddMon, 0)) {
                Console.WriteLine(ddMon.DeviceName);
                Console.WriteLine(ddMon.DeviceID);
                Console.WriteLine(ddMon.DeviceKey);
                Console.WriteLine(ddMon.DeviceString);
                Console.WriteLine();
                devMon++;
                ddMon.cb = Marshal.SizeOf(ddMon);
            }
            devNum++;
            dd.cb = Marshal.SizeOf(dd);
        }
        Console.ReadKey();
    }

    [DllImport("user32.dll")]
    public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct DISPLAY_DEVICE {
        [MarshalAs(UnmanagedType.U4)] public int cb;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string DeviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceString;
        [MarshalAs(UnmanagedType.U4)] public DisplayDeviceStateFlags StateFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceKey;
    }

    [Flags()]
    public enum DisplayDeviceStateFlags : int {
        AttachedToDesktop = 0x1,
        MultiDriver = 0x2,
        PrimaryDevice = 0x4,
        MirroringDriver = 0x8,
        VGACompatible = 0x16,
        Removable = 0x20,
        ModesPruned = 0x8000000,
        Remote = 0x4000000,
        Disconnect = 0x2000000
    }
}

如果您对该函数为何以如此奇怪的方式使用感兴趣,请阅读上面链接中该函数的文档。

尝试另一种方法,例如本机winapi函数。示例代码:

public class Program {
    private static void Main(string[] args) {
        var dd = new DISPLAY_DEVICE();
        dd.cb = Marshal.SizeOf(dd);
        uint devNum = 0;
        while (EnumDisplayDevices(null, devNum, ref dd, 0)) {
            uint devMon = 0;
            var ddMon = new DISPLAY_DEVICE();
            ddMon.cb = Marshal.SizeOf(ddMon);
            while (EnumDisplayDevices(dd.DeviceName, devMon, ref ddMon, 0)) {
                Console.WriteLine(ddMon.DeviceName);
                Console.WriteLine(ddMon.DeviceID);
                Console.WriteLine(ddMon.DeviceKey);
                Console.WriteLine(ddMon.DeviceString);
                Console.WriteLine();
                devMon++;
                ddMon.cb = Marshal.SizeOf(ddMon);
            }
            devNum++;
            dd.cb = Marshal.SizeOf(dd);
        }
        Console.ReadKey();
    }

    [DllImport("user32.dll")]
    public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct DISPLAY_DEVICE {
        [MarshalAs(UnmanagedType.U4)] public int cb;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string DeviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceString;
        [MarshalAs(UnmanagedType.U4)] public DisplayDeviceStateFlags StateFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string DeviceKey;
    }

    [Flags()]
    public enum DisplayDeviceStateFlags : int {
        AttachedToDesktop = 0x1,
        MultiDriver = 0x2,
        PrimaryDevice = 0x4,
        MirroringDriver = 0x8,
        VGACompatible = 0x16,
        Removable = 0x20,
        ModesPruned = 0x8000000,
        Remote = 0x4000000,
        Disconnect = 0x2000000
    }
}

如果您对该函数为何以如此奇怪的方式使用感兴趣,请阅读上面链接中该函数的文档。

嗯,它不会打印任何内容。。。我会试着调试。为我打印两个监视器,让你知道。它在我截图的机器上工作,但在我自己的电脑上不工作。(也许我使用的是Thunderbolt output中的Apple显示器?)但最重要的一点是,Display_DEVICE struct中没有序列号,只有DeviceID和DeviceKey非常相同,我猜它们不可靠——这意味着当你拔下并重新插入时,它们会发生变化。我需要一个唯一的ID,即使你改变了他们的连接端口,它也不会改变。。。我会试着调试。为我打印两个监视器,让你知道。它在我截图的机器上工作,但在我自己的电脑上不工作。(也许我使用的是Thunderbolt output中的Apple显示器?)但最重要的一点是,Display_DEVICE struct中没有序列号,只有DeviceID和DeviceKey非常相同,我猜它们不可靠——这意味着当你拔下并重新插入时,它们会发生变化。我需要一个唯一的ID,它不会改变,即使你改变他们的连接端口。