32位下C#自定义纸张尺寸打印正常,64位异常求助
64位环境下C#设置自定义打印纸张尺寸无效的解决方法
问题背景
需求:打印指定尺寸图片,打印机自动裁切纸张。
异常表现:32位环境下代码打印正常,但64位环境中,代码设置的纸张尺寸看似正确,打印机却按默认纸张尺寸裁切。手动在Windows设置中修改打印机纸张尺寸后,打印恢复正常,推测64位环境下C#代码无法正确修改该设置。
用户提供的原代码:
var pd = new PrintDocument(); pd.PrintPage += PrintThreeImagesPage; PrinterSettings printerSettings = new PrinterSettings(); printerSettings.PrinterName = "IP60 Photo"; pd.PrinterSettings = printerSettings; pd.DefaultPageSettings.PaperSize = GetCustomPaperSize(printerSettings, 608, 258); pd.Print(); private static PaperSize? GetCustomPaperSize(PrinterSettings printerSettings, int width, int height) { PaperSize? paperSize = null; foreach (PaperSize size in printerSettings.PaperSizes) { if (size.Width == width && size.Height == height) { paperSize = size; break; } } if (paperSize == null) { // If the custom paper size doesn't exist, create a new one Type type = typeof(PaperSize); paperSize = (PaperSize)type.InvokeMember("Custom", System.Reflection.BindingFlags.CreateInstance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, printerSettings, new object[] { "Custom", width, height }); } return paperSize; }
解决方法
1. 改用独立的PageSettings对象
64位环境下,直接修改PrintDocument.DefaultPageSettings可能无法正确将参数传递给打印机驱动,建议单独创建PageSettings并绑定:
var pd = new PrintDocument(); pd.PrintPage += PrintThreeImagesPage; var printerSettings = new PrinterSettings { PrinterName = "IP60 Photo" }; // 创建独立的PageSettings实例 var pageSettings = new PageSettings(printerSettings); pageSettings.PaperSize = GetCustomPaperSize(printerSettings, 608, 258); // 替换DefaultPageSettings pd.DefaultPageSettings = pageSettings; pd.Print();
2. 替换反射创建自定义PaperSize的逻辑
原代码使用反射调用非公开构造函数,64位环境下兼容性差,改用PaperSize的公开API创建自定义尺寸:
private static PaperSize GetCustomPaperSize(PrinterSettings printerSettings, int width, int height) { // 优先查找已存在的自定义尺寸 foreach (PaperSize size in printerSettings.PaperSizes) { if (size.PaperKind == PaperKind.Custom && size.Width == width && size.Height == height) { return size; } } // 用公开构造函数创建自定义尺寸 var customSize = new PaperSize("Custom", width, height); // 将尺寸添加到打印机支持列表(部分驱动要求) printerSettings.PaperSizes.Add(customSize); return customSize; }
3. 检查并更新64位打印机驱动
很多老打印机的32位驱动和64位驱动行为差异大,确认安装官方发布的64位驱动,避免使用兼容模式的32位驱动。部分64位驱动会忽略代码传递的自定义尺寸,仅读取系统预设值。
4. 强制锁定打印区域
在PrintPage事件中手动设置打印区域,确保输出匹配自定义纸张尺寸:
private void PrintThreeImagesPage(object sender, PrintPageEventArgs e) { var paperSize = e.PageSettings.PaperSize; // 取消边距限制 e.PageSettings.Margins = new Margins(0, 0, 0, 0); // 设置打印裁剪区域为整个纸张 e.Graphics.SetClip(new RectangleF(0, 0, paperSize.Width, paperSize.Height)); // 此处添加你的图片绘制逻辑 }
5. 通过Windows API修改打印机默认尺寸(需管理员权限)
如果以上方法都无效,可以调用Win32 API直接修改打印机的系统默认纸张尺寸,实现持久化设置:
// 引入Win32 API [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command); // 具体实现需结合PRINTER_INFO_9等结构体,可参考Windows SDK文档 // 注意:此操作需要管理员权限,适合需要固定默认纸张尺寸的场景
内容的提问来源于stack exchange,提问作者JoachimVeulemans
相关产品推荐
相关产品推荐

