Почему функции COM-объекта банковского терминала работают при отладке, но не срабатывают в обычном режиме 1С

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

При интеграции торгового оборудования, особенно банковских терминалов через COM-соединение, разработчики часто сталкиваются с мистической ситуацией: программный код идеально отрабатывает при пошаговой отладке, но в реальном режиме «1С:Предприятие» функции просто игнорируются. Разберем эту проблему на примере работы с терминалами Ingenico Desk/3200 и библиотекой ECRCommX.BPOS1Lib (протокол Arcus2).

Суть проблемы: когда отладка «спасает» код

Ситуация выглядит следующим образом: при вызове метода возврата Refund в обычном режиме работы терминал никак не реагирует, а состояние COM-объекта не меняется. Однако стоит поставить точку останова и пройти тот же самый код по шагам — всё начинает работать корректно, терминал оживает и запрашивает карту.

Проанализируем типовой код вызова функции:


ОбъектДрайвера.Refund(Сумма * 100, 0, Мерчант, КодRRN);
// В режиме отладки здесь терминал просит карту
// В обычном режиме — тишина

Первое подозрение обычно падает на асинхронность или нехватку времени для инициализации порта. Однако простая вставка пауз через Предупреждение или ПриОстановке часто не приносит результата. Рассмотрим причины, по которым это происходит.

Анализ причин конфликта COM-объектов

Основная причина такого поведения кроется в монопольном доступе к ресурсам. Библиотека ECRCommX.BPOS1Lib взаимодействует с физическим или виртуальным COM-портом (или TCP-сокетом). Если в системе создается еще один экземпляр этого же объекта или происходит попытка обращения к драйверу из другого потока/сеанса, библиотека может «зависнуть» или заблокировать выполнение команд.

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

Выясняем причину: влияние регламентных заданий

В процессе исследования выяснилось, что виновником блокировки часто выступает механизм регламентных заданий 1С. Рассмотрим цепочку событий:

  1. В системе настроен автоматический обмен данными или иное регламентное задание.
  2. В настройках задания (или в коде его запуска) установлена опция «Запускать отдельный сеанс».
  3. При старте этого фонового сеанса происходит инициализация общих модулей. Если в этих модулях или в процедуре ПриУстановкеПараметровСеанса прописана логика инициализации торгового оборудования, фоновый сеанс пытается «захватить» COM-объект.
  4. Библиотека ECRCommX не поддерживает многопоточность должным образом и блокирует доступ для основного пользовательского сеанса.

Важный момент: Операция Void (аннуляция) может работать, так как она часто выполняется по упрощенному протоколу без глубокой сверки с хостом, в то время как Refund (возврат) требует полнофункционального соединения и проверки всех параметров транзакции (RRN, суммы), что делает её более чувствительной к блокировкам драйвера.

Пошаговое решение проблемы

Для исправления ситуации выполним следующие действия:

  1. Проверка настроек регламентных заданий: Проанализируем список активных фоновых заданий. Если среди них есть те, что отвечают за обмен или загрузку данных, попробуйте временно отключить для них запуск в отдельном сеансе или вовсе приостановить их.
  2. Изоляция инициализации оборудования: Убедитесь, что создание объекта ECRCommX.BPOS1Lib происходит только в клиентском сеансе и только тогда, когда это необходимо. Не стоит инициализировать драйвер терминала «на всякий случай» при старте системы.
  3. Проверка RemoteApp и RDP: При использовании удаленного рабочего стола порты пробрасываются в сессию пользователя. Если регламентное задание запускается на сервере от имени того же пользователя, оно может конфликтовать с проброшенным портом. Проанализируем настройки COM-портов в диспетчере устройств на сервере.

Оптимизация кода взаимодействия с драйвером

Чтобы избежать подобных проблем в будущем, рекомендуется использовать защищенный механизм создания объекта. Рассмотрим пример:


Попытка
    ОбъектДрайвера = Новый COMОбъект("ECRCommX.BPOS1Lib");
Исключение
    Сообщить("Не удалось инициализировать драйвер терминала. Возможно, порт занят другим процессом.");
    Возврат;
КонецПопытки;

// Перед выполнением операции проверим готовность
Если ОбъектДрайвера.Init() <> 0 Тогда
    Сообщить("Ошибка инициализации устройства: " + ОбъектДрайвера.ErrorDescription);
Иначе
    Результат = ОбъектДрайвера.Refund(Сумма * 100, 0, Мерчант, КодRRN);
    // Обязательно анализируем код возврата
    Если Результат <> 0 Тогда
         ПроанализируемПричину(ОбъектДрайвера.ResultCode);
    КонецЕсли;
КонецЕсли;

Использование явной проверки ResultCode после вызова метода Refund позволит сразу увидеть причину отказа в обычном режиме. Часто там возвращается код, соответствующий ошибке "Device busy" или "Port locked".

Резюме

Если код в 1С работает только в режиме отладки, это верный признак конфликта ресурсов или проблем с таймингами. В случае с банковскими терминалами Arcus2 основной причиной является конкуренция за COM-объект со стороны фоновых процессов. Отключение флага запуска отдельного сеанса для регламентных заданий или перенос логики работы с оборудованием строго в клиентскую часть позволяет полностью устранить проблему «зависания» функций возврата и оплаты.

← На главную