c# 获取电脑 分辨率 及 DPI 设置

复制代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

/// <summary>
/// 这个可以
/// </summary>
class Program
{
    static void Main()
    {
        //设置DPI感知
        try
        {
            SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
        }
        catch
        {
            // 旧版Windows回退方案
            try
            {
                SetProcessDPIAware();
            }
            catch { }
        }
        try
        {
            // 获取所有显示器信息
            var monitors = GetAllMonitors();
            if (monitors.Count == 0)
            {
                Console.WriteLine("未检测到显示器");
                return;
            }
            // 创建或覆盖本地txt文件
            string filePath = @"C:\DisplayInfo.txt";
            using (StreamWriter writer = new StreamWriter(filePath))
            {
                writer.WriteLine("显示器信息报告");
                writer.WriteLine($"获取时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                writer.WriteLine($"检测到 {monitors.Count} 台显示器");
                foreach (var monitor in monitors)
                {
                    writer.WriteLine($"显示器名称: {monitor.DeviceName} {(monitor.IsPrimary ? "(主显示器)" : "")}");
                    writer.WriteLine($"分辨率: {monitor.Width} × {monitor.Height}");
                    writer.WriteLine($"DPI缩放百分比: {monitor.DpiScalePercent:F0}%");
                }
            }
            Console.WriteLine($"信息已写入文件:{filePath}");
            Console.WriteLine("按任意键打开文件...");
            Console.ReadKey();
            Process.Start("notepad.exe", filePath);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误:{ex.Message}");
        }
    }


    //DPI感知声明
    [DllImport("shcore.dll")]
    private static extern int SetProcessDpiAwareness(int value);

    private const int PROCESS_PER_MONITOR_DPI_AWARE = 2;

    //显示器API声明
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct MONITORINFOEX
    {
        public int Size;
        public RECT Monitor;
        public RECT WorkArea;
        public uint Flags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string DeviceName;
    }

    [DllImport("user32.dll")]
    private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip,
        MonitorEnumDelegate lpfnEnum, IntPtr dwData);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi);

    [DllImport("shcore.dll")]
    private static extern int GetDpiForMonitor(IntPtr hmonitor, int dpiType, out uint dpiX, out uint dpiY);

    [DllImport("user32.dll")]
    private static extern IntPtr GetDesktopWindow();

    [DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

    private delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);

    // 常量定义
    private const int MDT_EFFECTIVE_DPI = 0;
    private const int MONITOR_DEFAULTTOPRIMARY = 1;

    // 显示器信息类
    public class DisplayInfo
    {
        public string DeviceName { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        public double DpiScalePercent { get; set; }
        public bool IsPrimary { get; set; }
    }

    // 获取所有显示器信息的方法
    private static List<DisplayInfo> GetAllMonitors()
    {
        var displayInfos = new List<DisplayInfo>();
        MonitorEnumDelegate monitorDelegate = (IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData) =>
        {
            MONITORINFOEX mi = new MONITORINFOEX();
            mi.Size = Marshal.SizeOf(mi);
            if (GetMonitorInfo(hMonitor, ref mi))
            {
                uint dpiX = 96, dpiY = 96;
                bool isPrimary = (mi.Flags & 0x1) != 0;
                // 使用专用API获取DPI
                if (GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, out dpiX, out dpiY) != 0)
                {
                    // API失败时使用主显示器DPI
                    IntPtr primaryMonitor = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY);
                    GetDpiForMonitor(primaryMonitor, MDT_EFFECTIVE_DPI, out dpiX, out dpiY);
                }
                // 计算DPI百分比 (基于96 DPI为100%)
                double dpiScalePercent = Math.Round((dpiX / 96.0) * 100, 0);
                displayInfos.Add(new DisplayInfo
                {
                    DeviceName = mi.DeviceName.Trim(),
                    Width = mi.Monitor.Right - mi.Monitor.Left,
                    Height = mi.Monitor.Bottom - mi.Monitor.Top,
                    DpiScalePercent = dpiScalePercent,
                    IsPrimary = isPrimary
                });
            }
            return true;
        };
        EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, monitorDelegate, IntPtr.Zero);
        return displayInfos;
    }
}

新建控制台应用程序执行即可

如下,一台显示器:

多台显示器信息

相关推荐
小程故事多_802 小时前
Agent Infra核心技术解析:Sandbox sandbox技术原理、选型逻辑与主流方案全景
java·开发语言·人工智能·aigc
沐知全栈开发2 小时前
SQL 日期处理指南
开发语言
黎雁·泠崖2 小时前
【魔法森林冒险】3/14 Allen类(一):主角核心属性与初始化
java·开发语言
黎雁·泠崖2 小时前
【魔法森林冒险】1/14 项目总览:用Java打造你的第一个回合制冒险游戏
java·开发语言
独好紫罗兰2 小时前
对python的再认识-基于数据结构进行-a006-元组-拓展
开发语言·数据结构·python
C++ 老炮儿的技术栈2 小时前
Qt 编写 TcpClient 程序 详细步骤
c语言·开发语言·数据库·c++·qt·算法
yuuki2332332 小时前
【C++】继承
开发语言·c++·windows
222you2 小时前
Redis的主从复制和哨兵机制
java·开发语言
牛奔2 小时前
如何理解 Go 的调度模型,以及 G / M / P 各自的职责
开发语言·后端·golang
梵刹古音2 小时前
【C++】 析构函数
开发语言·c++