Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print PDF on default network printer using GhostScript (gswin32c.exe) shell command

I'd like to print PDF file(s) on windows' network printer via GhostScript.
(I dont want to use Adobe Reader)

I've read gswin32c.exe which can do the job.
I experimented with many commands and coudn't find the way how to force gs to print PDF on my (windows default) network drive.

I don't need point exact network printer- default can be used. But if there is no such option I'm happy to pass printer name as well. (I've tried with param -SDevice="\server_IP\printer_name" but this didnt work as well...)

Command working under Windows cmd:

gswin32c -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=1 -sDEVICE=ljet4 -sOutputFile="\\spool\\\Server_Name\Printer_name" "C:\test.pdf"

Method created base on above - doesnt work and thorws exception. (Error code = 1)

    /// <summary>
    /// Prints the PDF.
    /// </summary>
    /// <param name="ghostScriptPath">The ghost script path. Eg "C:\Program Files\gs\gs8.71\bin\gswin32c.exe"</param>
    /// <param name="numberOfCopies">The number of copies.</param>
    /// <param name="printerName">Name of the printer. Eg \\server_name\printer_name</param>
    /// <param name="pdfFileName">Name of the PDF file.</param>
    /// <returns></returns>
    public bool PrintPDF (string ghostScriptPath, int numberOfCopies, string printerName, string pdfFileName) {
        ProcessStartInfo startInfo  = new ProcessStartInfo();
        startInfo.Arguments         = " -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=" + Convert.ToString(numberOfCopies) + " -sDEVICE=ljet4 -sOutputFile=\"\\\\spool\\" + printerName + "\" \"" + pdfFileName + "\"";
        startInfo.FileName          = ghostScriptPath; 
        startInfo.UseShellExecute   = false;

        Process process = Process.Start(startInfo);

        return process.ExitCode == 0;
    }

Any idea how to make it working under C#?

like image 435
Maciej Avatar asked Apr 08 '10 12:04

Maciej


People also ask

How do I run Ghostscript?

The command line to invoke Ghostscript is essentially the same on all systems, although the name of the executable program itself may differ among systems. For instance, to invoke Ghostscript on unix-like systems type: gs [options] {filename 1} ... [options] {filename N} ...


4 Answers

Adding only -dPDFFitPage to my arguments fixed the same issue with the "top page content is often cut."

like image 179
zoom Avatar answered Sep 22 '22 11:09

zoom


I've finally made it working and easy for debugging.
My final method code for those interested:

    /// <summary>
    /// Prints the PDF.
    /// </summary>
    /// <param name="ghostScriptPath">The ghost script path. Eg "C:\Program Files\gs\gs8.71\bin\gswin32c.exe"</param>
    /// <param name="numberOfCopies">The number of copies.</param>
    /// <param name="printerName">Name of the printer. Eg \\server_name\printer_name</param>
    /// <param name="pdfFileName">Name of the PDF file.</param>
    /// <returns></returns>
    public bool PrintPDF (string ghostScriptPath, int numberOfCopies, string printerName, string pdfFileName) {
        ProcessStartInfo startInfo  = new ProcessStartInfo();
        startInfo.Arguments         = " -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=" + Convert.ToString(numberOfCopies) + " -sDEVICE=ljet4 -sOutputFile=\"\\\\spool\\" + printerName + "\" \"" + pdfFileName + "\" ";
        startInfo.FileName          = ghostScriptPath; 
        startInfo.UseShellExecute = false;

        startInfo.RedirectStandardError = true;
        startInfo.RedirectStandardOutput = true;

        Process process = Process.Start(startInfo);

        Console.WriteLine( process.StandardError.ReadToEnd() + process.StandardOutput.ReadToEnd() );

        process.WaitForExit(30000);
        if (process.HasExited == false) process.Kill();


        return process.ExitCode == 0;
    }
like image 33
Maciej Avatar answered Oct 16 '22 12:10

Maciej


Not sure if it helps anyone, but to add the printing documents to a queue instead of immediately printing make changes to the above section with

startInfo.Arguments = " -dPrinted -dNoCancel=true -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=" + Convert.ToString(numberOfCopies) + " -sDEVICE=mswinpr2 -sOutputFile=%printer%" + printerName + " \"" + pdfFullFileName + "\"";

Pre-requisites: Configure your printer's job type to "Hold Print": In our case we have a Rico Aficio MP 4000 Printer and our usage is to run a nightly job to print a bunch of PDF files generated through SSRS.

like image 4
Kiran Xyz Avatar answered Oct 16 '22 12:10

Kiran Xyz


You should test your options from the command line first, and then translate the successes into your code.

A PDF file usually does already include page margins. You "often cut" page content may result from a PDF which is meant for A4 page size printed on Letter format.

PDF also uses some internal boxes which organize the page (and object) content: MediaBox, TrimBox, CropBox, Bleedbox.

There are various options to control for which "media size" Ghostscript renders a given input:

-dPDFFitPage  
-dUseTrimBox  
-dUseCropBox 

With PDFFitPage Ghostscript will render to the current page device size (usually the default page size).

With UseTrimBox it will use the TrimBox (and it will at the same time set the PageSize to that value).

With UseCropBox it will use the CropBox (and it will at the same time set the PageSize to that value).

By default (give no parameter), Ghostscript will render using the MediaBox.

Note, you can additionally control the overall size of your output by using -sPAPERSIZE (select amongst all pre-defined values Ghostscript knows) or (for more flexibility) use -dDEVICEWIDTHPOINTS=NNN -dDEVICEHEIGHTPOINTS=NNN to set up custom page sizes.

like image 3
Kurt Pfeifle Avatar answered Oct 16 '22 11:10

Kurt Pfeifle