Как получить данные с COM-порта в 1С 8.3 x64?

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

При переходе на современные 64-разрядные платформы «1С:Предприятие 8.3» разработчики часто сталкиваются с аппаратной проблемой: старые, годами проверенные библиотеки для работы с последовательными (COM) портами отказываются запускаться. Инструменты вроде MSComm.ocx, vk_rs_232.dll или старые ActiveX-компоненты просто не могут быть загружены в 64-битный процесс платформы. Разберем по шагам, почему возникает эта проблема, как ее обойти с помощью штатных средств 1С, и проанализируем альтернативные способы интеграции торгового и промышленного оборудования.

Почему старые решения не работают в 1С x64?

Основная причина кроется в архитектурных ограничениях операционных систем и технологии COM/ActiveX. Давайте выясним ключевые моменты:

  1. Конфликт разрядности (32/64 бит). 64-битное приложение (каковым и является современный тонкий или толстый клиент 1С x64) физически не способно загрузить в свое адресное пространство 32-битную динамическую библиотеку (DLL). Большинство старых драйверов COM-порта были написаны в 32-битную эпоху и не имеют 64-битных аналогов.
  2. Проблемы с правами доступа. Компоненты ActiveX требуют обязательной регистрации в системном реестре Windows с помощью утилиты regsvr32. В современных ОС для этого требуются права администратора, что сильно усложняет развертывание и обновление системы на рабочих местах обычных пользователей.
  3. Ограничения веб-клиента и Linux. Технология ActiveX жестко привязана к операционной системе Windows и браузеру Internet Explorer. На компьютерах под управлением Linux или в веб-клиенте под управлением Chrome такие библиотеки работать не будут.

Решением этих проблем стала разработка новой технологии создания внешних компонент — Native API. Компоненты, написанные по этой технологии, загружаются напрямую платформой 1С, поставляются в виде общих макетов прямо внутри конфигурации и автоматически поддерживают нужную разрядность клиента (как 32, так и 64 бит).

Решение проблемы: использование Native API драйвера сканера штрихкодов

Как показывает практика, для получения текстовых данных из COM-порта не обязательно писать собственную компоненту или искать сомнительные платные решения. Мы можем воспользоваться штатным драйвером «1С:Сканер штрихкода» (AddIn.Scanner), который поставляется в составе «1С:Библиотеки подключаемого оборудования» (БПО) и присутствует практически во всех типовых конфигурациях (например, «1С:Розница», «1С:Управление торговлей» или «1С:ERP»).

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

Шаг 1. Извлечение и подготовка компоненты

Рассмотрим, где взять нужную компоненту. Нам необходимо открыть конфигурацию-донор (например, «1С:Розница») и найти в ветке Общие -> Общие макеты макет с именем Драйвер1ССканерШтрихкода (или аналогичный макет компоненты сканера штрихкодов в БПО). Выгрузим этот макет на диск в виде двоичных данных.

Затем в нашей целевой конфигурации создадим новый общий макет с типом Двоичные данные, назовем его, например, КомпонентаРаботыCOM и загрузим туда ранее сохраненный файл.

Шаг 2. Написание кода инициализации порта

Для того чтобы система начала прослушивать порт при старте программы, нам нужно инициализировать компоненту и настроить ее параметры. Рекомендуется выполнять этот код при начале работы системы в модуле управляемого приложения или в модуле обычного приложения (в зависимости от типа используемого клиента).

Разберем пример кода инициализации:


Процедура ПриНачалеРаботыСистемы()
    
    // Подключаем внешнюю компоненту из общего макета нашей конфигурации
    РезультатПодключения = ПодключитьВнешнююКомпоненту("ОбщийМакет.КомпонентаРаботыCOM", "Scanner", ТипВнешнейКомпоненты.Native);
    
    Если Не РезультатПодключения Тогда
        ЗаписатьЛогСобытий("Не удалось подключить внешнюю компоненту работы с COM-портом!");
        Возврат;
    КонецЕсли;
    
    // Создаем объект драйвера
    Попытка
        ОбъектДрайвера = Новый ("AddIn.Scanner.Scanner");
    Исключение
        ЗаписатьЛогСобытий("Не удалось создать объект драйвера сканера!");
        Возврат;
    КонецПопытки;
    
    // Настраиваем параметры подключения к COM-порту
    // Подсоединяем логическое устройство
    Результат = (ОбъектДрайвера.Подсоединить("СканерШтрихкода") = 0);
    
    // Задаем имя события, которое будет генерироваться при получении данных
    ОбъектДрайвера.ИмяСобытия = "ПолученыДанныеПорта";
    
    // Задаем кодировку, в которой устройство присылает строку
    ОбъектДрайвера.COMКодировка = "UTF-8"; 
    
    // Настройки порта (должны строго соответствовать настройкам самого устройства)
    ОбъектДрайвера.Порт = 1;         // Номер COM-порта (например, 1 для COM1)
    ОбъектДрайвера.Скорость = 9600;   // Скорость передачи данных в бодах
    ОбъектДрайвера.БитДанных = 8;     // Количество бит данных в байте
    
    // Критически важная настройка: символ окончания посылки данных.
    // Обычно устройства в конце строки присылают символ перевода строки (Line Feed - LF, или Carriage Return - CR)
    ОбъектДрайвера.СуффиксСтрока = Символы.ПС; 
    
    // Монопольно занимаем порт в операционной системе
    РезультатЗанятия = (ОбъектДрайвера.Занять(1) = 0);
    
    Если РезультатЗанятия Тогда
        // Включаем устройство и разрешаем отправку внешних событий в 1С
        ОбъектДрайвера.УстройствоВключено = 1;
        ОбъектДрайвера.ПосылкаДанных      = 1;
        
        // Очищаем буферы порта перед началом работы
        ОбъектДрайвера.ОчиститьВход();
        ОбъектДрайвера.ОчиститьВыход();
    Иначе
        ЗаписатьЛогСобытий("Не удалось занять COM-порт. Возможно, он занят другой программой.");
    КонецЕсли;

КонецПроцедуры

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

Шаг 3. Обработка полученных данных

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


Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
    
    // Проверяем, что событие пришло именно от нашего прослушивателя порта
    Если Источник = "СканерШтрихкода" И Событие = "ПолученыДанныеПорта" Тогда
        
        // В переменной "Данные" содержится строка, принятая из COM-порта
        ОчищенныеДанные = СокрЛП(Данные);
        
        // Вызываем логику обработки полученной строки
        ОбработатьПринятыеДанные(ОчищенныеДанные);
        
    КонецЕсли;

КонецПроцедуры

Процедура ОбработатьПринятыеДанные(Знач ТекстДанных)
    // Здесь размещается ваша прикладная бизнес-логика.
    // Например, парсинг веса с весов, вывод сообщения пользователю или запись в документ.
    ПоказатьОповещениеПользователя("Получены данные из порта:", , ТекстДанных);
КонецПроцедуры

Альтернативные методы интеграции без использования внешних компонент

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

Метод 1. Использование TCP-мостов (Редиректоров портов)

Существует класс программного обеспечения, преобразующий физический COM-порт в виртуальный сетевой TCP-порт (например, утилиты *HW VSP*, *com2tcp* или *Tibbo Virtual Serial Port*). Программа-мост постоянно слушает COM-порт локального компьютера и перенаправляет все приходящие байты на определенный сетевой порт (например, localhost:4001).

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

Метод 2. Использование фонового скрипта-посредника на Python

Если требуется высокая надежность и гибкая предварительная обработка данных, отличным решением станет написание небольшого скрипта на языке Python, который запускается в качестве службы ОС.

Скрипт использует библиотеку pyserial для чтения порта и отправляет данные в 1С через механизм публикации HTTP-сервисов. Проанализируем схему работы:

  1. На компьютере работает фоновый скрипт Python, который слушает порт COM1.
  2. В базе 1С создается и публикуется простой HTTP-сервис (например, с шаблоном пути /hs/DeviceData/).
  3. При получении строки из порта скрипт отправляет HTTP POST запрос на адрес вашей базы 1С, передавая принятые данные в теле запроса.
  4. 1С мгновенно принимает запрос в модуле HTTP-сервиса и запускает необходимую бизнес-логику на стороне сервера.

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

Особенности работы в среде Linux

Если ваши рабочие места или серверы 1С переводятся на операционные системы семейства Linux (например, Astra Linux или RedOS), учтите следующие особенности работы с портами:

Таким образом, использование штатных Native API компонент 1С позволяет элегантно и без дополнительных затрат решить проблему получения данных с COM-порта на современных 64-битных платформах, обеспечивая кроссплатформенность и простоту развертывания решения.

← На главную