views:

762

answers:

2

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#?

+1  A: 

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;
    }
Maciej
You should call process.Close() as well, after you get the exit code.
Fiona Holder
You are right - thanks
Maciej
Only issue I have with above method is page margins. I coudnt find solution how to set them up. SO my top page content is often cut. I wonder if someone knows how to resolve that?
Maciej
I've resolved fitting page to specified paper size by passing options via external cfg file.
Maciej
+1  A: 

You should test your options from the commandline 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.

pipitas