К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как получить список принтеров в 1С

Как получить список принтеров в 1С: метод ПолучитьИнформациюОПринтерах, WMI, PowerShell и выбор принтера пользователем. Примеры кода, ограничения и ошибки.

Задача получить список принтеров возникает, когда нужно дать пользователю выбор устройства печати, проверить доступность конкретного принтера перед отправкой документа или организовать печать этикеток и чеков на разные устройства из одного интерфейса. В 1С:Предприятии нет единственного «правильного» способа — доступные методы зависят от версии платформы, режима работы (тонкий, толстый, веб-клиент) и того, где выполняется код: на клиенте или на сервере.

Начиная с платформы 8.3.22 появился штатный метод ПолучитьИнформациюОПринтерах(), который закрывает большинство сценариев. Для более старых версий остаются обходные пути: WMI-запросы, PowerShell, чтение реестра или диалог выбора принтера. Ниже разобраны все варианты с примерами кода, их ограничения и типичные ошибки.

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

Штатный метод ПолучитьИнформациюОПринтерах (платформа 8.3.22 и новее)

Глобальный метод ПолучитьИнформациюОПринтерах() возвращает массив значений типа ИнформацияОПринтере. Каждый элемент содержит свойства: Имя — название принтера, ИмяДрайвера, Порт, ПринтерПоУмолчанию — признак устройства по умолчанию, Сетевой — признак сетевого принтера. Это самый простой и переносимый способ: он работает в тонком, толстом и веб-клиенте без дополнительных разрешений операционной системы.

Пример вывода списка в окно сообщений:

1C (BSL)
ИнформацияОПринтерах = ПолучитьИнформациюОПринтерах();
Для Каждого Принтер Из ИнформацияОПринтерах Цикл
    Сообщить(Принтер.Имя + " | Драйвер: " + Принтер.ИмяДрайвера
        + " | По умолчанию: " + Принтер.ПринтерПоУмолчанию
        + " | Сетевой: " + Принтер.Сетевой);
КонецЦикла;

Если нужно получить только имена для списка выбора, массив легко преобразовать в СписокЗначений и показать пользователю через ПоказатьВыборИзМеню или заполнить элемент формы. Признак ПринтерПоУмолчанию удобен, чтобы предложить пользователю предустановленный вариант.

Ограничение метода — он возвращает принтеры, доступные в том окружении, где выполняется код. При вызове в клиентской процедуре это принтеры рабочего места пользователя. Вызов на сервере вернёт принтеры, установленные на сервере 1С (и подключённые для учётной записи, под которой работает агент сервера), что часто пустой или неожиданный набор.

Получение списка принтеров через WMI

Для платформ старше 8.3.22 классический способ — запрос к WMI через COM-объект WbemScripting.SWbemLocator. Класс Win32_Printer содержит сведения обо всех принтерах, установленных в Windows: имя, порт, драйвер, сетевой ли принтер, устройство по умолчанию, состояние.

1C (BSL)
Локатор = Новый COMОбъект("WbemScripting.SWbemLocator");
Сервис = Локатор.ConnectServer(".", "root\cimv2");
Запрос = Сервис.ExecQuery("SELECT Name, PortName, DriverName, Network, Default FROM Win32_Printer");
Для Каждого Принтер Из Запрос Цикл
    Сообщить(Принтер.Name + " | " + Принтер.PortName + " | " + Принтер.DriverName);
КонецЦикла;

Этот код может выполняться только на клиенте под Windows и только в режиме, где разрешено создание COM-объектов. В тонком и веб-клиенте COM-автоматизация недоступна, поэтому WMI-подход применим в основном в толстом клиенте или в файловом режиме. При работе через RDP-сеанс запрос вернёт принтеры, видимые внутри сеанса, включая перенаправленные устройства.

Полезное свойство Default класса Win32_Printer позволяет найти принтер по умолчанию: добавьте условие WHERE Default = TRUE в запрос. Свойство WorkOffline помогает отфильтровать устройства, помеченные как автономные, — печать на них зависнет в очереди.

Получение списка через PowerShell и командную строку

Альтернатива WMI — запуск внешней команды и разбор её вывода. Команда Get-Printer в PowerShell возвращает список принтеров, а wmic printer get name делает то же самое через устаревшую, но ещё встречающуюся утилиту WMIC. Из 1С команду запускают через ЗапуститьПриложение или КомандаСистемы, перенаправляя вывод во временный файл, который затем читается построчно.

bash
powershell -NoProfile -Command "Get-Printer | Select-Object -ExpandProperty Name" > C:\Temp\printers.txt

Способ громоздкий: требует прав на запуск внешних приложений, создаёт временные файлы и зависит от настроек политики выполнения скриптов PowerShell. Применять его имеет смысл, когда нужны расширенные сведения, недоступные через простые запросы, — например, состояние очереди печати или количество заданий на устройстве.

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

Выбор принтера пользователем через диалог печати

Если цель — не получить список программно, а дать пользователю выбрать устройство, проще всего использовать штатный диалог печати. Метод Напечатать табличного документа с параметром РежимИспользованияДиалогаПечати.Использовать показывает стандартное окно, где пользователь сам выбирает принтер, число копий и диапазон страниц.

Для неинтерактивной печати на конкретное устройство используется свойство табличного документа ИмяПринтера: присвойте ему имя принтера (полученное любым из способов выше) и вызовите печать без диалога. Если имя указано с ошибкой или принтер недоступен, печать уйдёт на устройство по умолчанию или завершится ошибкой — поведение зависит от клиента и драйвера.

Порядок действий для печати на выбранный принтер
  1. 1
    Получите список принтеров методом ПолучитьИнформациюОПринтерах() или через WMI
  2. 2
    Покажите имена пользователю в списке выбора и сохраните выбранное значение
  3. 3
    Перед печатью проверьте, что принтер с таким именем всё ещё доступен в текущем списке
  4. 4
    Присвойте табличному документу свойство ИмяПринтера и вызовите Напечатать без диалога
  5. 5
    Проверьте результат на тестовом документе, прежде чем включать режим для всех пользователей

Имена принтеров чувствительны к точному написанию, включая регистр и пробелы. Сетевой принтер, подключённый как \\SERVER\HP4050, и локально установленный тот же принтер — разные имена. Храните выбранное имя в настройках пользователя (например, через ХранилищеОбщихНастроек), чтобы не запрашивать выбор при каждой печати.

Клиент и сервер: где выполнять код

Ключевая ошибка при работе с принтерами — непонимание, чьи устройства возвращает код. Таблица ниже помогает выбрать место выполнения в зависимости от сценария.

СценарийГде выполнятьЧто вернёт код
Пользователь печатает документ со своего рабочего местаКлиентПринтеры компьютера пользователя, включая перенаправленные в RDP
Фоновая печать, регламентные заданияСерверПринтеры, установленные на сервере 1С
Печать этикеток на локальный принтер складаКлиентЛокальные и сетевые принтеры рабочего места кладовщика
Веб-клиент через браузерКлиент (веб)Принтеры, доступные браузеру; COM и запуск команд недоступны

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

Контрольные точки

Как проверить результат

Состав списка
Норма

Имена совпадают с разделом «Принтеры и сканеры» в Windows на нужном компьютере

Тревожный признак

Список пуст или содержит чужие устройства — код выполняется не в том контексте (клиент/сервер)

Принтер по умолчанию
Норма

Признак ПринтерПоУмолчанию установлен ровно у одного устройства

Тревожный признак

Ни у одного принтера признак не установлен — у пользователя не назначено устройство по умолчанию

Пробная печать
Норма

Документ выходит на выбранном принтере без диалогов

Тревожный признак

Печать уходит на другое устройство — имя принтера задано неточно

Типичные ошибки и ограничения

Самая частая проблема — попытка использовать ПолучитьИнформациюОПринтерах() на платформе ниже 8.3.22. Проверяйте требования конфигурации или оборачивайте вызов в проверку версии через СистемнаяИнформация. Вторая типичная ситуация — код написан в серверной процедуре, а разработчик ожидает увидеть принтеры пользователя: в клиент-серверном режиме сервер ничего не знает о рабочем месте клиента.

В терминальных сессиях имена перенаправленных принтеров содержат суффикс вида «(перенаправлено N)», который меняется от сеанса к сеансу. Сохранять такое имя в настройках бессмысленно — при следующем входе оно не совпадёт. Надёжнее каждый раз получать актуальный список и сопоставлять по части имени.

Ещё одна ловушка — виртуальные принтеры (Microsoft Print to PDF, XPS Writer, отправка в OneNote). Они присутствуют в списке наравне с физическими. Если пользователь выбирает устройство для печати этикеток, стоит фильтровать список или явно предупреждать о виртуальных устройствах.

Типичные ошибки
01
Вызов ПолучитьИнформациюОПринтерах() на платформе старше 8.3.22 — ошибка «метод не определён»
02
Получение списка на сервере, когда печатает клиент, — список не совпадает с устройствами пользователя
03
Сохранение имени перенаправленного RDP-принтера в настройки — после переподключения имя меняется, печать уходит не туда
04
Создание COM-объектов в серверном коде — риск аварийного завершения рабочего процесса сервера
05
Игнорирование виртуальных принтеров — пользователь случайно «печатает» в PDF вместо физического устройства

Часто задаваемые вопросы

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

На платформе 8.3.22+ переберите результат ПолучитьИнформациюОПринтерах() и найдите элемент с признаком ПринтерПоУмолчанию = Истина. На старых версиях выполните WMI-запрос SELECT Name FROM Win32_Printer WHERE Default = TRUE — он вернёт единственное устройство.

Почему ПолучитьИнформациюОПринтерах возвращает пустой массив?

Чаще всего код выполняется на сервере, где для учётной записи агента 1С не установлено ни одного принтера. Перенесите вызов в клиентскую процедуру или подключите принтеры на сервере под нужной учётной записью. Также проверьте, что версия платформы не ниже 8.3.22.

Можно ли получить список принтеров в веб-клиенте?

Штатный метод ПолучитьИнформациюОПринтерах() в веб-клиенте работает, но возвращает устройства, доступные браузерному окружению. COM-объекты, WMI и запуск внешних команд в веб-клиенте недоступны, поэтому для старых платформ обходных путей в браузере практически нет — используйте диалог печати.

Как напечатать табличный документ на конкретный принтер без диалога?

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

Почему сохранённое имя принтера перестаёт работать в терминальном режиме?

Перенаправленные в RDP принтеры получают суффикс с номером сеанса, который меняется при каждом подключении. Храните не полное имя, а постоянную часть названия, и при каждом сеансе ищите совпадение в актуальном списке принтеров.

Как отличить физический принтер от виртуального в списке?

Надёжного штатного признака нет. Ориентируйтесь на имя драйвера и порта: виртуальные устройства (Microsoft Print to PDF, XPS) используют порты вида PORTPROMPT или подобные, а не USB, TCP/IP или LPT. При необходимости ведите список исключаемых имён в настройках.

Итог

Что важно запомнить

На платформе 8.3.22+ список принтеров получают методом ПолучитьИнформациюОПринтерах(), на старых версиях — через WMI или PowerShell. Всегда учитывайте контекст выполнения: клиент видит принтеры пользователя, сервер — только свои. Для печати на конкретное устройство используйте свойство ИмяПринтера табличного документа и проверяйте доступность принтера перед отправкой.