在C# .NET 6.0.29 API中打印PDF遇InvalidPrinterException问题求助
.NET 6 API PDF打印异常排查与解决
问题背景
在C# .NET 6.0.29编写的API中,已通过iTextSharp成功生成PDF文件,但打印时触发System.Drawing.Printing.InvalidPrinterException。确认能ping通打印机IP、打印机名称正确、网络连接正常且具备打印权限,但打印操作始终失败,实现代码如下:
private static bool PrintPdf(string filePath, string printerIpAddress) { string printerName = printerIpAddress; try { using (var document = new System.Drawing.Printing.PrintDocument()) { var printerSettings = new System.Drawing.Printing.PrinterSettings(); printerSettings.PrinterName = printerName; document.PrinterSettings = printerSettings; document.PrintPage += (sender, e) => { Log.Information("Événement PrintPage déclenché"); try { using (var stream = new FileStream(filePath, FileMode.Open)) { using (var image = System.Drawing.Image.FromStream(stream)) { e.Graphics.DrawImage(image, e.MarginBounds); } } } catch (Exception ex) { Log.Error("Erreur lors de la lecture du fichier PDF : " + ex.Message); } }; document.Print(); return true; } } catch (InvalidPrinterException ex) { Debug.WriteLine("Exception InvalidPrinterException : " + ex.Message); Debug.WriteLine("StackTrace : " + ex.StackTrace); return false; } catch (Exception ex) { Debug.WriteLine("Erreur lors de l'impression du document : " + ex.Message); return false; } }
问题根源
- 打印机名称参数错误:代码直接将IP地址作为打印机名称传入,但
PrinterSettings.PrinterName需要的是系统注册的打印机全名(比如"HP LaserJet Pro M404dn (192.168.1.100)"),而非纯IP字符串。 - PDF处理逻辑错误:用
Image.FromStream读取PDF流完全无效,PDF并非图片格式,这会导致打印逻辑异常,甚至间接触发打印机识别错误。 - .NET 6环境兼容性问题:
System.Drawing.Printing依赖GDI+,在无桌面会话的API服务器环境中支持有限,容易出现权限或设备识别类问题。
解决步骤
1. 正确获取对应IP的打印机名称
编写方法枚举系统内已安装的打印机,匹配目标IP对应的打印机全名:
private static string GetPrinterNameByIp(string printerIp) { foreach (string printer in PrinterSettings.InstalledPrinters) { var settings = new PrinterSettings { PrinterName = printer }; try { // 检查打印机端口是否包含目标IP if (settings.PortName.Contains(printerIp)) { return printer; } } catch { // 跳过无法访问的打印机 continue; } } return null; }
替换原代码中string printerName = printerIpAddress的逻辑:
string printerName = GetPrinterNameByIp(printerIpAddress); if (string.IsNullOrEmpty(printerName)) { Log.Error("未找到对应IP的打印机"); return false; }
2. 使用专业库处理PDF打印
放弃依赖GDI+的错误方式,采用PdfiumViewer(轻量且适配.NET 6)实现PDF打印:
首先安装NuGet包:PdfiumViewer
重写打印逻辑如下:
using PdfiumViewer; using System.Drawing.Printing; private static bool PrintPdf(string filePath, string printerIpAddress) { string printerName = GetPrinterNameByIp(printerIpAddress); if (string.IsNullOrEmpty(printerName)) { Log.Error("未找到对应IP的打印机"); return false; } try { using (var pdfDoc = PdfDocument.Load(filePath)) using (var printDoc = pdfDoc.CreatePrintDocument()) { printDoc.PrinterSettings.PrinterName = printerName; // 可选:设置边距为0,适配无边界打印需求 printDoc.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0); printDoc.Print(); return true; } } catch (InvalidPrinterException ex) { Debug.WriteLine($"打印机异常: {ex.Message}\n堆栈信息: {ex.StackTrace}"); return false; } catch (Exception ex) { Debug.WriteLine($"打印出错: {ex.Message}"); return false; } }
3. 服务器环境适配
若API部署在无桌面会话的服务器上:
- 确保打印机为网络直连型,服务器无需通过桌面映射即可访问
- 运行API的服务账号(如IIS应用池账号)需具备打印权限
- 避免所有依赖GDI+的打印方式,优先使用PdfiumViewer这类跨环境库
内容的提问来源于stack exchange,提问作者Bastien Gayet
相关产品推荐
相关产品推荐

