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;
    }
}

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

如下,一台显示器:

多台显示器信息

相关推荐
玖玥拾6 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾6 小时前
Rust 学习目录
开发语言·学习·rust
云泽8087 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
灯澜忆梦7 小时前
GO---可见性规则
开发语言·golang
逝水无殇7 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
这是个栗子8 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
凤凰院凶涛QAQ8 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
研☆香8 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
右耳朵猫AI8 小时前
PHP周刊2026W28 | 安全更新、Laravel 13.18、Twig 3.28
开发语言·php·laravel
second608 小时前
第一部分:快速上手 —— 建立 C++ 基本语法与编程范式
开发语言·c++