Почему не идет печать на перенаправленный чековый принтер в RDP и как это исправить?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Проблема с печатью на чековые принтеры в терминальной сессии (RDP) — это классическая ситуация, с которой сталкиваются многие разработчики при работе с обычными формами 1С:Предприятие 8.3. Ситуация часто выглядит так: принтер виден в системе, программный код находит его имя, команда Напечатать() выполняется без ошибок, но в очереди печати ничего не появляется. При этом, если вывести документ на экран и выбрать тот же принтер вручную, всё работает корректно. Разберем подробно причины этого поведения и способы решения задачи.

Анализ механизма именования принтеров в RDP

Первая и самая очевидная причина кроется в динамическом изменении имен принтеров. Когда пользователь подключается по RDP, его локальный принтер пробрасывается на сервер с суффиксом, например: (перенаправлено 5) или (redirected 2). Номер сессии меняется при каждом новом подключении. Рассмотрим, почему это критично для 1С.

Если в коде или в настройках макета (файл параметров печати пользователя) сохранено старое имя принтера, 1С будет пытаться отправить задание на несуществующий объект. Даже если вы используете WSHNetwork.EnumPrinterConnections() для поиска актуального имени, платформа может игнорировать программную установку, если в самом табличном документе уже "зашито" имя из предыдущей сессии.

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


ТабДок = Новый ТабличныйДокумент;
// ... формирование документа ...
ТабДок.ИмяПринтера = НужноеИмяПринтера; 
ТабДок.ПараметрыСтраницы.ИмяПринтера = НужноеИмяПринтера;
ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);

Проблема Microsoft Remote Desktop Easy Print

Одной из главных скрытых причин проблем с чековыми (POS) принтерами является технология Easy Print. По умолчанию Windows пытается использовать универсальный драйвер для всех проброшенных устройств. Это удобно для офисных принтеров, но губительно для чековых лент, так как универсальный драйвер не понимает специфических команд (обрезка, управление денежным ящиком) и может некорректно обрабатывать нестандартные размеры страниц.

Выясним, как это лечится. Необходимо заставить сервер использовать "родной" драйвер принтера, установленный непосредственно на сервере (он должен совпадать с драйвером на локальном ПК). Для этого системному администратору нужно изменить групповые политики (GPO):

Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Перенаправление принтеров.

Здесь нужно установить параметр "Использовать в первую очередь драйвер принтера Easy Print удаленного рабочего стола" в состояние "Отключено".

Особенности формата имени принтера и порты NeXX

Посмотрим на пример того, как система возвращает имя принтера. Часто при перечислении через COM-объекты или WMI имя выглядит как ИмяПринтера (перенаправлено 5) на Ne01:. Для метода 1С Напечатать() часть строки, начинающаяся со слова "на" или "on", может быть лишней или приводить к ошибке инициализации задания печати.

Рекомендуется очищать полученную строку. Рассмотрим по шагам, как это сделать:

  1. Получаем полный список принтеров.
  2. Ищем нужный принтер по маске (например, по модели).
  3. Обрезаем все символы, начиная с " на " или " on ", чтобы оставить только чистое системное имя.

Функция ОчиститьИмяПринтера(ИсходноеИмя)
    Поз = Найти(ИсходноеИмя, " на ");
    Если Поз > 0 Тогда
        Возврат Лев(ИсходноеИмя, Поз - 1);
    КонецЕсли;
    Поз = Найти(ИсходноеИмя, " on ");
    Если Поз > 0 Тогда
        Возврат Лев(ИсходноеИмя, Поз - 1);
    КонецЕсли;
    Возврат ИсходноеИмя;
КонецФункции

Права доступа и папка Spooler

Разберем ситуацию, когда задание создается, но тут же пропадает. Даже если код выполняется "на клиенте", фактически процесс 1cv8.exe работает в контексте вашей RDP-сессии на сервере. Для формирования задания печати пользователю необходимы права на запись в системную директорию C:\Windows\System32\spool\PRINTERS на серверной ОС.

Если прав недостаточно, очередь печати не сможет сформировать временный файл задания. Проверьте права пользователя или попробуйте запустить 1С от имени администратора (для теста), чтобы исключить этот фактор.

Альтернативное решение через внешнюю печать

Если стандартные методы 1С (Напечатать или Печать) продолжают игнорировать принтер, проанализируем вариант с обходом механизмов платформы. Это наиболее надежный способ для "капризных" китайских драйверов (XPrinter, Zjiang).

Суть метода заключается в сохранении чека во временный файл и отправке его на печать через командную строку операционной системы. Посмотрим на алгоритм:

  1. Сохраняем ТабличныйДокумент в формат PDF или MXL.
  2. Используем легкую утилиту (например, SumatraPDF), которая умеет печатать из командной строки и "понимает" перенаправленные принтеры лучше, чем 1С.
  3. Вызываем печать через ЗапуститьПриложение().

ПутьКФайлу = КаталогВременныхФайлов() + "ticket.pdf";
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);

КомандаПечати = """C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to """ + НужноеИмяПринтера + """ -silent """ + ПутьКФайлу + """";
ЗапуститьПриложение(КомандаПечати, , Истина);

Этот способ позволяет полностью избежать проблем с кэшированием настроек принтера внутри 1С и некорректной передачей параметров страницы через GDI-интерфейс платформы.

Очистка кэша настроек печати

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

Попробуйте следующее: Удалите содержимое папки %AppData%\1C\1cv8\ (кэш пользователя). При следующем запуске 1С "забудет" старое имя принтера и корректно инициализирует его из кода. Также полезно в самом коде перед печатью устанавливать ТабДок.ПараметрыСтраницы.ИмяПринтера = "", а затем уже присваивать актуальное значение.

Проанализировав все вышеперечисленные факторы — от настроек GPO до программной очистки имен — вы сможете обеспечить стабильную работу чекового принтера в любой терминальной среде.

← На главную