C# Printing problem with system.Drawing.Printing from #web API

Manivannan D 1 Reputation point
2021-04-15T10:46:22.073+00:00
Hello everyone,  
  
I have a situation to print PDF document as a batch from Web API.   
And I have used System.Drawing.Printing Library to print them.  
  
I have noticed the ‘Caution’ mentioned on Microsoft site (https://learn.microsoft.com/en-us/dotnet/api/system.drawing.printing?view=net-5.0) as below.  
  
Specifications:  
1)	We are using network printers.  
2)	Windows server 2016 standard.  
  
Caution:  
Classes within the System.Drawing.Printing namespace are not supported for use within a Windows service or ASP.NET application or service.   
Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions.  
  
As mentioned in the caution I am facing some unexpected problems intermittently during print operation as below.  
  
Problems:  
1)	Pages are missing in the PDF documents. Example: Out of 10 pages 5th page is missed.  
2)	Documents are missing, example: out of 100 documents 99/ 95 printed. Some of them is missed.   
  
Exception occured in PrintPdf method: The handle is invalid System.ComponentModel.Win32Exception (0x80004005): The handle is invalid  
   at System.Drawing.Printing.StandardPrintController.OnStartPrint(PrintDocument document, PrintEventArgs e)  
   at System.Drawing.Printing.PrintController.Print(PrintDocument document)  
   at System.Drawing.Printing.PrintDocument.Print()  
  
  
Code snippet:  
  
    using (var document = _pdfDocumentWrapper.Load(stream))  
                {  
                    using (var printDocument = _pdfDocumentWrapper.CreatePrinterDocument(document))  
                    {  
                        var printerName = printerconfiguration;  
                        Print(printDocument, printerName);  
                    }  
                }  
      
    private void Print(PrintDocument printDocument, string printerName)  
            {  
                                  
                var printerSettings = new PrinterSettings { PrinterName = printerName };  
                var pageSettings = new PageSettings(printerSettings) { Margins = new Margins(0, 0, 0, 0) };  
                printDocument.PrinterSettings = printerSettings;  
                printDocument.DefaultPageSettings = pageSettings;  
                printDocument.PrintController = new StandardPrintController();  
                printDocument.BeginPrint += PrintDocument_BeginPrint;  
                printDocument.PrintPage += PrintDocument_PrintPage;  
                printDocument.EndPrint += PrintDocument_EndPrint;  
                  
                printDocument.Print();  
            }  
  
Any suggestions or alternative approach for the same would be greatly appreciated.  
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,774 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,617 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Michael Taylor 54,316 Reputation points
    2021-04-15T14:12:54.343+00:00

    It really depends upon what you intend to do with that printout. If you're printing a physical document for a user then how do they get the document. Your web server could be hosted on premise or the cloud. It might or might not have access to a printer near the person who needs it. In most cases the better solution is to do the printing client side. You can write javascript to print a batch of PDFs on the printer(s) available to the client. This eliminates the need for server-side printing. Of course the user could also just open the PDF and print from their PDF viewer as well.

    If you need to print the PDF so you can manipulate them then don't bother printing, just use a PDF library like iText or equivalent and do your PDF manipulation.

    If you really need to print a PDF to a printer then, ignoring the issue of the printer not being accessible, you'll want to move the process out of band. In the few cases where I've needed to do this we created a simple console app that did the printing. The console app was run using the Process task but it ran using credentials of a local user which ensured the local printers on the machine were used. Of course this has bad performance since starting a process with an interactive user is going to be slow (relatively speaking). You could also create a console app that hosts a WCF service (or if you're using .NET Core then hosting Kestrel directly) that your API then communicates with. The console app would need to be started when the server starts but shouldn't really be a Windows service since that is not supported either. There are loads of problems with this approach but it helps perf a little bit.

    Finally the best option, in my opinion, is to write a batching processor that runs periodically (via scheduled tasks perhaps). The API would simply add the print request to some shared queue (probably a database or messaging queue). The batching processor, when it runs, would pick up things to print and then print them. If using a database then the processor could update the status when done. The API would provide a corresponding endpoint to check the status of the printing so the user could be notified (if relevant). Note that the API would not want to wait on the printing to complete as it could take longer than a web request. This is what the 202 HTTP status code is for - I've started the processing but I'm not done yet, here's some ID that you can use to query for the completion status later.


  2. MT 0 Reputation points
    2024-07-30T04:58:11.4733333+00:00

    Can someone from microsoft please respond to this issue? please?


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.