При разработке корпоративных систем часто возникает задача автоматической печати документов. Если на клиенте мы можем легко использовать встроенный метод Напечатать(), то в серверном контексте (например, в фоновом задании или в модуле, выполняемом на стороне сервера) этот метод оказывается недоступен. Это связано с тем, что серверный процесс 1С работает в так называемой "Сессии 0", где отсутствует графический интерфейс и контекст принтеров пользователя.
В данной статье мы разберем по шагам, как решить эту проблему, используя различные инструменты командной строки и программные методы, доступные для интеграции с 1С.
Прежде чем мы перейдем к техническим решениям, проанализируем ситуацию с точки зрения системного администрирования. Служба 1С:Предприятия обычно запускается от имени специальной учетной записи (например, USR1CV8). У этой учетной записи нет рабочего стола и, что более важно, нет настроенных по умолчанию принтеров.
Важный момент: Для успешной работы любого из нижеперечисленных методов принтер должен быть установлен на сервере как локальный (через TCP/IP порт) и доступен для всех пользователей системы. Сетевые принтеры, подключенные в сессии администратора, серверная служба 1С просто "не увидит".
Рассмотрим использование легкой и бесплатной утилиты SumatraPDF. Она примечательна тем, что не требует полноценной установки (может работать как portable-версия) и крайне быстро обрабатывает команды печати без "зависания" процессов.
Для реализации печати из 1С мы подготовим следующий код:
Процедура ПечатьPDFНаСервере(ПутьКФайлу, ИмяПринтера)
// Формируем строку запуска.
// Параметр -print-to указывает целевой принтер
// Параметр -silent подавляет все диалоговые окна
ПутьКПрограмме = "C:\Program Files\SumatraPDF\SumatraPDF.exe";
СтрокаЗапуска = """" + ПутьКПрограмме + """ -print-to """ + ИмяПринтера + """ -silent """ + ПутьКФайлу + """";
// Используем ЗапуститьПриложение для выполнения команды
ЗапуститьПриложение(СтрокаЗапуска, , Истина);
КонецПроцедуры
Преимущество этого метода заключается в том, что SumatraPDF корректно завершает свою работу после отправки задания в спулер печати, не оставляя лишних процессов в памяти сервера.
Если на сервере уже установлен Adobe Acrobat Reader, мы можем воспользоваться его штатными ключами командной строки. Однако выясним причину, по которой этот метод считается менее надежным: Adobe Reader часто оставляет процесс AcroRd32.exe открытым после печати, что может привести к утечке памяти на сервере.
Синтаксис команды выглядит следующим образом:
// Ключ /t: путь, имя_принтера, имя_драйвера, имя_порта
Команда = "AcroRd32.exe /t ""C:\Docs\file.pdf"" ""HP_LaserJet_400"" ""HP Universal Printing PCL 6"" ""IP_192.168.1.50""";
ЗапуститьПриложение(Команда);
Обратите внимание, что необходимо указать не только имя принтера, но и имя драйвера, а также порт. Это делает настройку более жесткой и зависимой от конфигурации конкретного сервера.
Существует узкоспециализированный инструмент PDFtoPrinter, созданный специально для решения нашей задачи. Он не имеет графического интерфейса и идеально подходит для работы в фоновых заданиях 1С.
Посмотрим на пример использования:
ПутьКУтилите = "C:\Tools\PDFtoPrinter.exe";
ИмяФайла = "C:\Temp\Order_123.pdf";
ИмяПринтера = "Office_Printer";
// Формируем команду: Утилита.exe Файл Принтер
СтрокаКоманды = """" + ПутьКУтилите + """ """ + ИмяФайла + """ """ + ИмяПринтера + """";
ЗапуститьПриложение(СтрокаКоманды, , Истина);
Эта утилита отлично справляется с именами принтеров, содержащими пробелы или кириллицу, что часто становится камнем преткновения при использовании обычного CMD.
В ситуациях, когда требуется высокая точность рендеринга или печать на специфическом оборудовании, проанализируем возможности Ghostscript. Это мощный движок обработки PDF и PostScript.
Для печати на Windows-принтер используется устройство mswinpr2:
КомандаGS = "gswin64c.exe -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -sDEVICE=mswinpr2 -sOutputFile=""%printer%Имя_Вашего_Принтера"" ""C:\input.pdf""";
ЗапуститьПриложение(КомандаGS, , Истина);
Важные параметры:
-dNOPAUSE и -dBATCH гарантируют, что программа закроется сразу после завершения обработки, не ожидая нажатия клавиши пользователем.
Если установка стороннего ПО на сервер запрещена политиками безопасности, мы можем использовать возможности PowerShell. Он позволяет обратиться к методам операционной системы для печати документа через зарегистрированный в системе обработчик.
Рассмотрим реализацию:
КомандаPS = "powershell.exe -Command ""Start-Process -FilePath 'C:\docs\file.pdf' -Verb Print -PassThru | %{ sleep 5; $_.Kill() }""";
ЗапуститьПриложение(КомандаPS, , Истина);
Проанализируем этот код: мы запускаем процесс печати через глагол Print, ждем 5 секунд (чтобы файл успел уйти в очередь) и принудительно закрываем приложение-обработчик. Это "грязный", но рабочий способ для систем без сторонних утилит.
Даже если команда печати составлена верно, она может не сработать. Выясним основные причины:
USR1CV8 (или того, под которым запущен сервер 1С) есть права "Печать" в свойствах безопасности принтера.ЗапуститьПриложение сервер 1С может не знать полных путей к исполняемым файлам. Всегда указывайте полные пути к .exe файлам и к самим документам PDF."""HP LaserJet 1020""".Session 0 это окно никто не увидит и не нажмет. Поэтому ключи -silent или -quiet обязательны.Подводя итог, выберем наиболее подходящий инструмент в зависимости от ваших условий:
Применяя эти подходы, вы сможете эффективно автоматизировать печать документов прямо из логики серверных модулей 1С, обеспечивая бесперебойную работу бизнес-процессов без участия пользователя.