You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows 10的C# .NET 8.0控制台程序中获取打印机默认页面方向

获取Windows 10打印机默认页面方向的C# .NET 8实现

针对你的需求,这里提供两种可行的实现方式:

方式一:使用System.Drawing.Printing命名空间

这是最简便的方法,依赖.NET的System.Drawing.Common组件,适合大多数场景。

步骤1:安装依赖包

控制台项目需要手动安装System.Drawing.Common NuGet包,可通过Package Manager控制台执行:

Install-Package System.Drawing.Common

或在NuGet包管理器中搜索安装。

步骤2:实现代码

using System.Drawing.Printing;

namespace PrinterOrientationDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string targetPrinter = "Microsoft Print to PDF";
            
            using var printerSettings = new PrinterSettings();
            printerSettings.PrinterName = targetPrinter;

            // 验证打印机是否存在
            if (!printerSettings.IsValid)
            {
                Console.WriteLine($"错误:打印机「{targetPrinter}」未安装");
                return;
            }

            // 获取默认页面方向
            bool isLandscape = printerSettings.DefaultPageSettings.Landscape;
            string orientation = isLandscape ? "横向(Landscape)" : "纵向(Portrait)";
            
            Console.WriteLine($"打印机「{targetPrinter}」的默认页面方向:{orientation}");
        }
    }
}

方式二:调用Win32 API(底层实现)

如果需要更底层的控制,或者不想依赖System.Drawing组件,可以直接调用Windows的打印API获取DEVMODE结构中的方向信息。

实现代码

using System;
using System.Runtime.InteropServices;

namespace PrinterOrientationWin32Demo
{
    class Program
    {
        private const int PRINTER_ACCESS_USE = 0x00000008;
        private const int ERROR_INSUFFICIENT_BUFFER = 122;

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct PRINTER_DEFAULTS
        {
            public IntPtr pDatatype;
            public IntPtr pDevMode;
            public int DesiredAccess;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct DEVMODE
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string dmDeviceName;
            public short dmSpecVersion;
            public short dmDriverVersion;
            public short dmSize;
            public short dmDriverExtra;
            public int dmFields;
            public short dmOrientation; // 0=纵向, 1=横向
            // 省略其他无关字段
        }

        [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, ref PRINTER_DEFAULTS pDefault);

        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool GetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int cbBuf, out int pcbNeeded);

        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool ClosePrinter(IntPtr hPrinter);

        static void Main(string[] args)
        {
            string targetPrinter = "Microsoft Print to PDF";
            IntPtr printerHandle = IntPtr.Zero;
            var defaults = new PRINTER_DEFAULTS { DesiredAccess = PRINTER_ACCESS_USE };

            try
            {
                // 打开打印机句柄
                if (!OpenPrinter(targetPrinter, out printerHandle, ref defaults))
                {
                    Console.WriteLine($"打开打印机失败,错误码:{Marshal.GetLastWin32Error()}");
                    return;
                }

                // 获取所需缓冲区大小
                int bufferSize = 0;
                GetPrinter(printerHandle, 2, IntPtr.Zero, 0, out bufferSize);
                if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
                {
                    Console.WriteLine("获取打印机信息失败");
                    return;
                }

                // 分配缓冲区并读取打印机信息
                IntPtr printerInfoBuffer = Marshal.AllocHGlobal(bufferSize);
                try
                {
                    if (!GetPrinter(printerHandle, 2, printerInfoBuffer, bufferSize, out bufferSize))
                    {
                        Console.WriteLine($"读取打印机信息失败,错误码:{Marshal.GetLastWin32Error()}");
                        return;
                    }

                    // 提取DEVMODE结构
                    IntPtr devModePtr = Marshal.ReadIntPtr(printerInfoBuffer + 8); // PRINTER_INFO_2中pDevMode的偏移量
                    if (devModePtr != IntPtr.Zero)
                    {
                        var devMode = Marshal.PtrToStructure<DEVMODE>(devModePtr);
                        string orientation = devMode.dmOrientation == 1 ? "横向(Landscape)" : "纵向(Portrait)";
                        Console.WriteLine($"打印机「{targetPrinter}」的默认页面方向:{orientation}");
                    }
                    else
                    {
                        Console.WriteLine("无法获取打印机的DEVMODE配置");
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(printerInfoBuffer);
                }
            }
            finally
            {
                // 关闭打印机句柄
                if (printerHandle != IntPtr.Zero)
                {
                    ClosePrinter(printerHandle);
                }
            }
        }
    }
}

说明

  • 方式一简单易用,但依赖System.Drawing.Common组件,该组件仅在Windows平台受支持(符合你的Windows 10场景)。
  • 方式二直接调用系统API,无额外依赖,适合对兼容性或底层控制有要求的场景。

内容的提问来源于stack exchange,提问作者Alexey Titov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:41:10