能否从.NET Core 3.1 Windows服务中打印文档?

6

tl;dr:如何从.NET Core 3.1 Windows服务打印PDF文件?

我创建了一个简单的打印池BackgroundService类,作为Windows服务运行,并通过Web API监视打印队列,工作得很愉快。

但是,当我开始编写实际的打印代码时,发现了一个小问题,即似乎.NET Core不允许从BackgroundService类打印文档。

System.Printing的文档也似乎暗示了这一点。

不支持在Windows服务或ASP.NET应用程序或服务中使用System.Printing命名空间中的类。尝试从其中一个应用程序类型中使用这些类可能会产生意想不到的问题,例如降低服务性能和运行时异常。

System.Drawing.Printing的文档也有类似的说明,指出它对于Windows服务也不能可靠地工作。

BackgroundService Windows服务打印是不好的吗?是否有明显的替代方案,我的(简短)谷歌搜索未能找到?打印要求应该很简单,我有PDF字节数组数据,只需要以某种方式将其发送到打印机即可。

我意识到我可以像将池转换为Console应用程序一样,然后从计划任务中运行它,但Windows服务模型似乎更简单,只需安装并忘记即可(它将被放置在仓库旁边的PC上)

非常感谢任何有帮助的建议。


我一直在ASP.NET Core服务器上使用System.Drawing.Printing。你试过使用这个库吗?虽然我还没有在.NET Core中编写服务,所以我不太确定是否有所不同。 - Ginger Ninja
谢谢GN,但是你的应用程序有图形用户界面吗?System.Drawing.Printing上的文档明确说明它在Windows服务中无法可靠工作。 - Ted
我没有为打印服务编写GUI。然而,我通过代码手动创建位图,然后将其作为打印任务发送。(这是用于QR码打印的) - Ginger Ninja
2个回答

2

令人难以置信的是,我们成功地实现了不可能完成的任务 - 从 .net Core 3.1 Windows 服务中打印 PDF。

我们使用 FreeSpire.PDF v5.4.0 nuget 包 和以下代码将预生成的 PDF 数据打印到 Zebra 标签打印机上。

bool printedOK = true;
string printErrorMessage = "";
try
{
    PdfDocument pdf = new PdfDocument(printJobResult.printJob.PrintData);
    pdf.PrintSettings.PrinterName = jobInfo.PrinterAddress;
    pdf.PrintSettings.DocumentName = jobInfo.Type == PrintJobType.Label ? $"Label {jobInfo.OrderNumber}" : $"DeliveryNote {jobInfo.OrderNumber}";                                    
    if(jobInfo.Type == PrintJobType.Label)
    {
        pdf.PrintSettings.PaperSize = new System.Drawing.Printing.PaperSize("Custom", _labelWidth, _labelHeight);
        pdf.PrintSettings.SetPaperMargins(2, 2, 2, 2);
    }
    pdf.PrintSettings.SelectSinglePageLayout(Spire.Pdf.Print.PdfSinglePageScalingMode.FitSize, true);
    _logger.LogDebug($"Paper Size - Width:{pdf.PrintSettings.PaperSize.Width} Height:{pdf.PrintSettings.PaperSize.Height} Name:{pdf.PrintSettings.PaperSize.PaperName} Kind:{pdf.PrintSettings.PaperSize.Kind} RawKind:{pdf.PrintSettings.PaperSize.RawKind}");

    pdf.Print();
}
catch (Exception ex)
{
    printErrorMessage = "Printing Error: " + ex.ToString();
    printedOK = false;
}

注意事项 - 一定要检查以下细节...

新版本的FreeSpire.PDF插件不允许打印,即使是5.4.0版本也有限制(我想是只能打印10页),但是对于我们的目的来说,该插件的5.4.0版本已经允许我们创建一个整洁小巧的交付标签打印池,作为运行在仓库PC上的Windows服务。


0

我为了自己的目的做了一个小测试,发现这对我有效。我的测试适用于 .txt 和 .pdf 文件。.png 文件只打印了一些错误代码和无法阅读的文本。

public Task StartAsync(CancellationToken cancellationToken)
{
    FileInfo fileInfo = new FileInfo(@"c:\temp\my_pdf.pdf");
    fileInfo.CopyTo(PrinterName);            
    return Task.CompletedTask;
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接