Разработчики 1С часто сталкиваются с ситуацией, когда код, идеально работающий на локальном компьютере программиста, отказывается функционировать при переносе на сервер. Типичный пример — автоматическая печать PDF-документов через метод ЗапуститьПриложение. На клиентском месте PDF-ридер открывается и печатает файл, а на сервере процесс либо «зависает», либо завершается без какого-либо результата. В этой статье мы подробно разберем, почему это происходит, и рассмотрим надежные способы реализации серверной печати.
Главная причина, по которой ЗапуститьПриложение не работает на сервере, кроется в архитектуре операционной системы Windows. Служба 1C:Enterprise Server работает в так называемой «Сессии 0». Это специальный неинтерактивный сеанс, предназначенный исключительно для служб.
Рассмотрим ключевые ограничения Сессии 0:
USR1CV8). У этого пользователя часто нет прав на доступ к сетевым принтерам, установленным в профиле администратора, или на чтение определенных веток реестра.Использование интерактивных PDF-ридеров типа Adobe Acrobat Reader на стороне сервера является плохой практикой. Проанализируем типичные ошибки при работе с ними:
Во-первых, после выполнения команды печати процессы типа AcroRd32.exe часто остаются висеть в памяти сервера, не завершаясь автоматически. Это приводит к утечке ресурсов и со временем парализует работу системы.
Во-вторых, параметры командной строки Adobe Reader (такие как /p, /t) официально не задокументированы и могут вести себя непредсказуемо в разных версиях программы.
Для стабильной работы на сервере необходимо использовать инструменты, специально предназначенные для работы в консольном режиме без графического интерфейса. Рассмотрим наиболее эффективные варианты.
SumatraPDF — это легкий и быстрый просмотрщик, который отлично поддерживает управление через командную строку. Рассмотрим пример кода для отправки файла на печать через 1С:
// Формируем путь к утилите и параметры печати
ПутьКПрограмме = """C:\Program Files\SumatraPDF\SumatraPDF.exe""";
ИмяПринтера = "HP_LaserJet_Pro_M402";
ПутьКФайлу = """C:\Temp\Document.pdf""";
// Параметр -print-to позволяет отправить файл на конкретный принтер без открытия окна
Команда = ПутьКПрограмме + " -print-to """ + ИмяПринтера + """ " + ПутьКФайлу;
// Используем ЗапуститьПриложение с ожиданием завершения
ЗапуститьПриложение(Команда, , Истина);
В данном примере мы используем параметр ДождатьсяЗавершения = Истина. Это позволяет серверному потоку 1С контролировать процесс печати. Если программа отработает корректно, поток пойдет дальше. Обратите внимание на использование тройных кавычек — это необходимо для корректной передачи путей с пробелами в командную строку Windows.
Для более сложных задач и максимальной надежности профессионалы рекомендуют Ghostscript. Это мощный интерпретатор языка PostScript и PDF, который работает напрямую с очередью печати Windows.
Проанализируем пример формирования команды для Ghostscript:
ПутьКGS = "C:\gs\gs9.54.0\bin\gswin64c.exe";
Принтер = "\\Server\Printer1";
Файл = "C:\Files\report.pdf";
Команда = ПутьКGS + " -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=1 -sDEVICE=mswinpr2 -sOutputFile=""%printer%" + Принтер + """ """ + Файл + """";
// Запуск через КомандаСистемы позволяет получить код возврата
КодВозврата = 0;
КомандаСистемы(Команда, КодВозврата);
Если КодВозврата <> 0 Тогда
ЗаписьЖурналаРегистрации("ПечатьPDF", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка печати: " + КодВозврата);
КонецЕсли;
Преимущество КомандаСистемы заключается в получении кода завершения. Если КодВозврата не равен 0, мы можем зафиксировать ошибку в Журнале регистрации и оперативно отреагировать на проблему.
При реализации серверной печати важно учитывать следующие технические моменты:
"""" + Путь + """".USR1CV8 (или другой, под которым запущен сервер 1С) имеет права «Печать» на целевом принтере. Если принтер сетевой, лучше подключать его по IP-адресу (TCP/IP Port), так как сессия службы не видит сетевые подключения обычных пользователей.ПолучитьИмяВременногоФайла("pdf"), но помните, что на сервере временные файлы создаются в папке профиля службы 1С. Убедитесь, что внешнее приложение имеет доступ к этой директории.Если вы все же хотите использовать стандартные ассоциации файлов Windows, можно попробовать объект Shell.Application, однако это решение также может быть нестабильным в контексте сервера:
// Пример использования COM-объекта Shell
Shell = Новый COMОбъект("Shell.Application");
// Метод ShellExecute с глаголом "print"
// Параметр 0 скрывает окно приложения
Shell.ShellExecute(ВремФайл, "", "", "print", 0);
Подытожим: Если ваша задача — стабильная печать документов в фоновом режиме (например, из регламентного задания), забудьте о методе ЗапуститьПриложение в связке с Adobe Reader на стороне сервера. Используйте SumatraPDF или Ghostscript. Это обеспечит бесперебойную работу системы и избавит вас от «зависших» процессов в диспетчере задач сервера.