Как распечатать PDF на сетевом принтере по умолчанию с помощью команды оболочки GhostScript (gswin32c.exe)

Я хочу распечатать файл(ы) PDF на сетевом принтере Windows с помощью GhostScript.
(я не хочу использовать Adobe Reader)

Я прочитал файл gswin32c.exe, который может выполнить эту работу.
Я экспериментировал со многими командами и не смог найти способ, как заставить gs печатать PDF на моем сетевом диске (по умолчанию в Windows) .

Мне не нужно указывать точный сетевой принтер — можно использовать значение по умолчанию. Но если такой опции нет, я также рад передать имя принтера. (Я пробовал с параметром -SDevice="\server_IP\printer_name", но это тоже не сработало...)

Команда, работающая под Windows cmd:

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

Метод, созданный на основе вышеизложенного, не работает и вызывает исключение. (Код ошибки = 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;
    }

Есть идеи, как заставить его работать под C#?


person Maciej    schedule 08.04.2010    source источник
comment
Извините, но то, что вы планируете вызывать это из своего приложения C #, не делает это проблемой программирования, я бы предложил SuperUser для этого вопроса Ghostscript и проголосовал за то, чтобы этот вопрос был перемещен туда для вас.   -  person Lazarus    schedule 08.04.2010
comment
Я отредактировал сообщение, чтобы теперь оно было более специфичным для С#.   -  person Maciej    schedule 08.04.2010


Ответы (4)


Наконец-то я сделал его работающим и удобным для отладки.
Мой окончательный код метода для тех, кто заинтересован:

    /// <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;
    }
person Maciej    schedule 08.04.2010
comment
Вы также должны вызвать process.Close() после получения кода выхода. - person Fiona - myaccessible.website; 08.04.2010
comment
Единственная проблема, с которой я столкнулся при использовании вышеуказанного метода, - это поля страницы. Я не нашел решения, как их настроить. ТАКИМ ОБРАЗОМ, содержание моей главной страницы часто обрезается. Интересно, знает ли кто-нибудь, как это решить? - person Maciej; 19.04.2010
comment
Я решил подогнать страницу под указанный размер бумаги, передав параметры через внешний файл cfg. - person Maciej; 07.06.2010
comment
Этот код отлично работает на локальной машине, когда я развертываю на сервере 2008, он не печатает файл PDF? Так ты(@Maciej) можешь показать мне, как это сделать. Я использую asp.net mvc - person dev; 07.11.2012
comment
Что касается вызова process.Close(), что, если я обернул процесс в оператор using?: using(Process process = Process.Start(startInfo)) - person Vincent Vancalbergh; 04.03.2013
comment
Есть ли способ распечатать документ без совместного использования принтера? - person user3079364; 31.01.2018

Не уверен, что это кому-нибудь поможет, но чтобы добавить документы для печати в очередь вместо немедленной печати, внесите изменения в приведенный выше раздел с помощью

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

Предварительные условия. Настройте тип задания принтера на «Отложенная печать». В нашем случае у нас есть принтер Rico Aficio MP 4000, и мы используем ночное задание для распечатать кучу PDF-файлов, созданных с помощью SSRS.

person Kiran Xyz    schedule 24.01.2014
comment
как это выглядит в командной строке? Я не могу заставить часть сетевого принтера работать. я выполняю это в пакетном задании - person user3015739; 02.03.2016
comment
изменение -sDEVICE с ljet3 на mswinpr2 помогло мне. Я печатаю в Windows. - person Kristianne Nerona; 09.12.2019

Вы должны сначала проверить свои параметры из командной строки, а затем перенести успехи в свой код.

Файл PDF обычно уже включает поля страницы. Ваше «часто вырезаемое» содержимое страницы может быть получено из PDF-файла, предназначенного для страницы формата A4, напечатанной в формате Letter.

PDF также использует некоторые внутренние поля, которые упорядочивают содержимое страницы (и объекта): MediaBox, TrimBox, CropBox, Bleedbox.

Существуют различные параметры для управления тем, для какого «размера носителя» Ghostscript отображает данный ввод:

-dPDFFitPage  
-dUseTrimBox  
-dUseCropBox 

С PDFFitPage Ghostscript будет отображать текущий размер страницы на устройстве (обычно размер страницы по умолчанию).

С UseTrimBox он будет использовать TrimBox (и в то же время установит PageSize на это значение).

С UseCropBox он будет использовать CropBox (и в то же время установит PageSize на это значение).

По умолчанию (без указания параметра) Ghostscript будет отображать файлы с расширением MediaBox.

Обратите внимание, что вы можете дополнительно контролировать общий размер вашего вывода, используя -sPAPERSIZE (выберите среди всех предопределенных значений, которые знает Ghostscript) или (для большей гибкости) используйте -dDEVICEWIDTHPOINTS=NNN -dDEVICEHEIGHTPOINTS=NNN для настройки пользовательских размеров страницы.

person Kurt Pfeifle    schedule 05.06.2010

Добавление только -dPDFFitPage к моим аргументам устранило ту же проблему с часто вырезаемым содержимым верхней страницы.

person zoom    schedule 16.02.2021