如何在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
相关产品推荐
相关产品推荐

