Sending file to print not working using System.Dra

2019-09-07 20:37发布

问题:

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.

回答1:

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");


回答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.