0

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.

Miquel Coll
  • 759
  • 15
  • 49

2 Answers2

2

You can not just write PDF bytes to a print job. The printer doesn't know how to handle it. The RAW data you send to the printer must describe the document in a printer language specific to the printer. That's what the printer driver does.

You can not print a PDF by just sending it to the printer. You need some piece of software that renders the PDF and then sends the rendered image to the printer.

As the documentation states:

Use this method to write device specific information, to a spool file, that is not automatically included by the Microsoft Windows spooler.

I enhanced the important part of this information.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • True. The printer won't know how to read a pdf file. I'm trying to render the pdf file now before Sending it to the printer (transforming it to a PNG) or using the lubrary suggested by Remus. I'm on it. – Miquel Coll Jun 16 '15 at 11:54
2

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");
Miquel Coll
  • 759
  • 15
  • 49
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • I know that this is not a licensing-expert platform, but are there any implications on how your software must be licensed for using Ghostscript? – Thorsten Dittmar Jun 16 '15 at 11:37
  • It's kinda working. I installed the licence and added the .dll reference and the file was sent to print :); Now I'm just trying to figure out how to use the print system preferences since it's printing page by page instead of 2-sides copies. I'lll keep you informed. – Miquel Coll Jun 16 '15 at 11:53
  • @ThorstenDittmar Licensing is [AGPL](https://github.com/jhabjan/Ghostscript.NET/blob/master/COPYING), not exactly as liberal as MIT, but neither as constraining as LGPL. Something for OP to consider, obviously. – Remus Rusanu Jun 16 '15 at 12:09
  • 1
    @MiquelColl the same link has an example as how to set Duplex printing (2-sided): *The following example shows how to print on both faces of the paper (using the long side of the paper as the reference):* `<< /Duplex true /Tumble false >> setpagedevice` – Remus Rusanu Jun 16 '15 at 12:13
  • ir works nice! There are some problems with the margins which the same documentation mentions but I can make a work-around around that. Thank you Remus. – Miquel Coll Jun 16 '15 at 12:44