Как настроить автоматическую печать на сервере 1С без участия пользователя?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

Разработчики систем на платформе 1С часто сталкиваются с техническим ограничением: когда данные в систему поступают из внешних источников (например, мобильное приложение курьера, терминал сбора данных или сайт через веб-сервис), необходимо мгновенно отправить документ на печать. Однако, если попытаться вызвать метод ТабДок.Напечатать() на стороне сервера, в фоновом задании или внутри веб-сервиса, платформа выдаст ошибку, так как серверная часть 1С не имеет прямого доступа к принтерам и интерактивному контексту.

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

Почему стандартная печать не работает из фонового задания?

Прежде чем перейти к программным решениям, выясним причину, по которой операционная система блокирует попытки сервера 1С отправить документ на принтер напрямую:

  1. Изоляция сессий (Session 0 Isolation): Служба сервера 1С (обычно это ragent.exe) выполняется в изолированной сессии Windows «Session 0». В этой сессии полностью отсутствует графический интерфейс (GUI). Любая внешняя программа (будь то Acrobat Reader, Microsoft Word или браузер), которую пытается вызвать сервер 1С для вывода на печать, пытается инициализировать окно интерфейса, зависает в памяти сервера и блокирует выполнение потока.
  2. Отсутствие окружения пользователя: Системная учетная запись, под которой работает служба 1С (например, usr1cv8), часто не имеет инициализированного профиля Windows. Из-за этого у нее нет доступа к сетевым принтерам и даже к временным папкам рабочего стола, которые необходимы подсистеме печати Windows для рендеринга.
  3. Права доступа к спулеру печати: Принтеры, установленные у обычных пользователей, не видны системной службе 1С, пока они не будут установлены локально на самом сервере для всех пользователей компьютера.

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

Решение 1. Создание выделенного «сеанса-робота» на стороне клиента

Это классический и самый надежный способ обхода ограничений серверной печати, который не зависит от системных настроек Windows и разрядности сервера. Идея заключается в следующем: при авторизации обычного пользователя (например, кассира, у которого всегда открыта 1С) система автоматически запускает на его компьютере еще один тонкий или толстый клиент 1С под специальным пользователем «РоботПечати».

Этот вспомогательный сеанс работает скрытно (без панелей меню и лишних прав), открывает обработку ожидания и каждую секунду проверяет специальный регистр сведений, куда веб-сервис записывает данные для печати. Так как этот сеанс запущен в интерактивном режиме на клиенте, у него есть полный доступ ко всем принтерам и стандартному методу ТабДок.Напечатать().

Рассмотрим по шагам реализацию этого механизма в модуле обычного приложения (на примере «1С:Управление торговлей 10.3»):


// Функция определяет тип информационной базы (файловая или клиент-серверная)
// для корректного формирования параметров командной строки запуска.
Функция ОпределитьЭтаИнформационнаяБазаФайловая(СтрокаСоединенияСБД = "") Экспорт
    СтрокаСоединенияСБД = ?(ПустаяСтрока(СтрокаСоединенияСБД), СтрокаСоединенияИнформационнойБазы(), СтрокаСоединенияСБД);
    ПозицияПоиска = Найти(Врег(СтрокаСоединенияСБД), "FILE=");
    Возврат ПозицияПоиска = 1;
КонецФункции

// Функция проверяет, активен ли уже сеанс робота печати.
// Если сеанс не запущен, функция программно стартует новый процесс 1С.
Функция ЗапуститьДополнительныйСеансПечати() Экспорт
    ИмяПользователя = Константы.ПользовательПечати.Получить();
    Если НЕ ЗначениеЗаполнено(ИмяПользователя) Тогда
        Возврат "Не указан пользователь для печати";
    КонецЕсли;
    
    СоединенияИнформационнойБазы = ПолучитьСоединенияИнформационнойБазы();
    ПользовательАктивен = Ложь;
    
    Для Каждого Соединение Из СоединенияИнформационнойБазы Цикл
        Если ИмяПользователя = Соединение.Пользователь.Имя Тогда
            ПользовательАктивен = Истина;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ПользовательАктивен Тогда
        // Сеанс печати уже запущен и выполняет свою работу
        Возврат "";
    КонецЕсли;
    
    ЭтоФайловаяИБ = ОпределитьЭтаИнформационнаяБазаФайловая();
    СтрокаСоединенияСБД = СтрокаСоединенияИнформационнойБазы();
    СтрокаПодключения = ?(ЭтоФайловаяИБ, " /F ", " /S ");
    
    Если Найти(Врег(СтрокаСоединенияСБД), "FILE=") > 0 Тогда
        СтрокаПодключения = СтрокаПодключения + Сред(СтрокаСоединенияСБД, 6, СтрДлина(СтрокаСоединенияСБД) - 6);
    Иначе
        СтрокаПодключения = СтрокаПодключения + Сред(СтрокаСоединенияСБД, 6, СтрДлина(СтрокаСоединенияСБД) - 6);
        СтрокаПодключения = СтрЗаменить(СтрокаПодключения, """;Ref=""", "\");
    КонецЕсли;
    
    ПарольПользователя = "ПарольРоботаПечати"; 
    СтрокаКоманды = КаталогПрограммы() + "1cv8.exe" + " ENTERPRISE" + СтрокаПодключения + " /N" + ИмяПользователя + " /P" + ПарольПользователя;
    
    // Запускаем приложение в асинхронном режиме
    ЗапуститьПриложение(СтрокаКоманды);
    Возврат "";
КонецФункции

Теперь разберем, как инициализировать запуск этого робота при старте программы. В модуле обычного приложения добавим обработку события ПриНачалеРаботыСистемы:


Процедура ПриНачалеРаботыСистемы()
    // Проверяем, запущен ли текущий сеанс под учетной записью робота печати
    Если ИмяПользователя() = Константы.ПользовательПечати.Получить() Тогда
        ЗапуститьПечать();
        Возврат;
    КонецЕсли;
    
    // Если зашел обычный кассир, проверяем активность робота и запускаем его при необходимости
    Если РазрешитьЗапускДополнительногоСеансаПечати Тогда
        ЗапуститьДополнительныйСеансПечати();
    КонецЕсли;
КонецПроцедуры

Процедура ЗапуститьПечать()
    // Проверяем, чтобы робот не запустился дважды на разных ПК
    СоединенияИнформационнойБазы = ПолучитьСоединенияИнформационнойБазы();
    КоличествоСеансов = 0;
    Для Каждого Соединение Из СоединенияИнформационнойБазы Цикл
        Если Константы.ПользовательПечати.Получить() = Соединение.Пользователь.Имя Тогда
            КоличествоСеансов = КоличествоСеансов + 1;
        КонецЕсли;
    КонецЦикла;
    
    Если КоличествоСеансов > 1 Тогда
        // Сеанс уже запущен на другом рабочем месте, закрываем текущий дубль
        ЗавершитьРаботуСистемы(Ложь);
        Возврат;
    КонецЕсли;
    
    // Открываем служебную обработку, которая будет циклически опрашивать базу данных
    ОбработкаПечати = Обработки.ОбработкаЗаданийНаПечать.Создать();
    ОбработкаПечати.ФоновоеВыполнение = Истина;
    ОбработкаПечати.ПринудительноОткрыть = Истина;
    ФормаОбработки = ОбработкаПечати.ПолучитьФорму("Форма");
    ФормаОбработки.Открыть();
КонецПроцедуры

Внутри формы обработки ОбработкаЗаданийНаПечать необходимо настроить интервал ожидания. Делается это с помощью метода ПодключитьОбработчикОжидания("ПроверитьЗаданияНаПечать", 1). Процедура ПроверитьЗаданияНаПечать будет считывать новые записи из регистра сведений, формировать макеты документов и отправлять их на печать стандартным вызовом ТабДок.Напечатать(Истина) без вывода диалога выбора принтера.

Решение 2. Консольная печать PDF-файлов напрямую с сервера

Если заказчик категорически против запуска дополнительных сеансов 1С на компьютерах пользователей, нам потребуется организовать печать непосредственно из службы сервера 1С. Для этого мы сохраняем печатную форму в формате PDF, а затем отправляем этот файл на принтер с помощью консольных утилит.

Чтобы этот метод работал стабильно и процессы не зависали в памяти сервера Windows, необходимо выполнить обязательную системную настройку профиля службы 1С.

Шаг 1: Подготовка окружения Windows на сервере

Для корректной работы подсистем печати у системной учетной записи должны существовать папки Desktop. Создайте их вручную по следующим путям:

Важно: Выдайте полные права (Full Control) на созданные папки учетной записи, от имени которой запущена служба «Агент сервера 1С:Предприятия» (по умолчанию это usr1cv8).

Шаг 2: Выбор консольной утилиты для "тихой" печати

Стандартный Adobe Acrobat Reader плохо подходит для серверной работы, так как оставляет открытым окно программы после отправки файла. Вместо него мы рассмотрим бесплатные и легковесные альтернативы.

Вариант А: Использование SumatraPDF (Наиболее простой и стабильный способ)

SumatraPDF — это легковесный просмотрщик, поддерживающий полноценную работу через командную строку без вывода графических окон. Пример запуска печати из 1С выглядит следующим образом:


ПутьКPDF = "G:\Test.pdf";
ИмяПринтера = "HP_LaserJet_Pro_M402";
СтрокаЗапуска = """C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to """ + ИмяПринтера + """ -print-settings ""noscale"" """ + ПутьКPDF + """";

// Запускаем скрытый процесс выполнения печати
ЗапуститьПриложение(СтрокаЗапуска, , Истина);

Параметр -print-settings "noscale" указывает программе отправлять документ «как есть», без принудительного масштабирования полей, а третий параметр метода ЗапуститьПриложение со значением Истина заставляет 1С дождаться окончания процесса отправки файла в спулер печати.

Вариант Б: Использование Ghostscript (Промышленный стандарт для Linux и Windows северов)

Если вам требуется максимальная надежность и гибкость, воспользуйтесь бесплатным интерпретатором Ghostscript. Он изначально ориентирован на консольную работу и без проблем функционирует в изолированной сессии сервера.


ПутьКPDF = "C:\Temp\document.pdf";
ИмяПринтера = "Brother_HL_L2300D";
СтрокаЗапуска = """C:\Program Files\gs\gs10.01.1\bin\gswin64c.exe"" -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -sDEVICE=mswinpr2 -sOutputFile=""%printer%" + ИмяПринтера + """ """ + ПутьКPDF + """";

ЗапуститьПриложение(СтрокаЗапуска, , Истина);

Параметр -sDEVICE=mswinpr2 указывает Ghostscript взаимодействовать напрямую с диспетчером печати Windows, что гарантирует моментальный вывод документа на бумагу без отображения каких-либо промежуточных окон.

Сравнение подходов

Выбор оптимального метода зависит от архитектуры вашей информационной системы:

← На главную