Search code examples
c#asp.netprintingsystem.drawingprintqueue

Sending file to print not working using System.Drawing.Printing


I'm trying to send a file to print without opening it trough Adobe as suggested by several Answers here; instead, I'm using the PrintQueue library (from System.Drawing.Printing).

What I've accomplished so far:

I have the correct PrintQueue referenced as pq:

PrintQueue pq; //Assume it's correct. The way to get here it isn't easy and it is not needed for the question.

// Call AddJob
PrintSystemJobInfo myPrintJob = pq.AddJob();

// Write a Byte buffer to the JobStream and close the stream
Stream myStream = myPrintJob.JobStream;
Byte[] myByteBuffer = ObjectIHave.ToArray(); //Ignore the ObjectIhave, it actually is Linq object which is correct as well.
myStream.Write(myByteBuffer, 0, myByteBuffer.Length);
myStream.Close();

As I understood from the Microsoft Library it's correctly done but it is not working. Any ideas?

EDIT: Debugging the code I can see that something is being send to the printer but it seems the file is not sent.


Solution

  • You need to render your PDF to the printer. Calling the shell print verb on the file would be the ideal means to do that. If you insist on doing the low level rendering yourself then I recommend using a library like Ghostscript.NET and choose the mswinpr2 device as output.

    The mswinpr2 device uses MS Windows printer drivers, and thus should work with any printer with device-independent bitmap (DIB) raster capabilities. The printer resolution cannot be selected directly using PostScript commands from Ghostscript: use the printer setup in the Control Panel instead.

    See SendToPrinterSample.cs for example:

            string printerName = "YourPrinterName";
            string inputFile = @"E:\__test_data\test.pdf";
    
            using (GhostscriptProcessor processor = new GhostscriptProcessor())
            {
                List<string> switches = new List<string>();
                switches.Add("-empty");
                switches.Add("-dPrinted");
                switches.Add("-dBATCH");
                switches.Add("-dNOPAUSE");
                switches.Add("-dNOSAFER");
                switches.Add("-dNumCopies=1");
                switches.Add("-sDEVICE=mswinpr2");
                switches.Add("-sOutputFile=%printer%" + printerName);
                switches.Add("-f");
                switches.Add(inputFile);
    
                processor.StartProcessing(switches.ToArray(), null);
            }
    

    If the file has to be printed in both sides you just need to add:

    switches.Add("-dDuplex");
    switches.Add("-dTumble=0");