Как освободить COM-порт после работы сканера ШК во внешней обработке 1С в режиме RDP

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

При работе с торговым оборудованием в среде удаленных рабочих столов (RDP) часто возникает неприятная ситуация: внешняя обработка успешно подключает сканер, всё работает, но после закрытия формы порт остается «зависшим». При повторном открытии обработки или попытке другого пользователя подключиться к оборудованию 1С выдает ошибку «Порт занят». Особенно остро эта проблема проявляется на серверах под управлением Windows Server 2008 и при использовании устаревших библиотек типа scanopos.dll.

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

Разберем причину: почему порт остается занятым?

Проанализируем ситуацию. В локальном режиме (на физической машине) драйвер обычно корректно освобождает COM-порт при уничтожении объекта. Однако в терминальной сессии (RDP) используется механизм перенаправления портов (COM-mapping). Когда 1С закрывает объект, терминальная служба может продолжать удерживать дескриптор (handle) виртуального порта, считая сессию активной. Если сервер виртуализирован (Hyper-V или VMware), ситуация усугубляется за счет дополнительных уровней абстракции USB-контроллера.

Решение 1. Соблюдение строгой последовательности деактивации в коде

Одной установки Сканер = Неопределено; часто бывает недостаточно, так как COM-объект может оставаться в памяти из-за счетчика ссылок. Нам необходимо принудительно дать команду драйверу освободить устройство. Рассмотрим правильный алгоритм в процедуре ПриЗакрытии или ПередЗакрытием формы:


Процедура ПриЗакрытии()
    Если ОбъектСканер <> Неопределено Тогда
        Попытка
            // 1. Сначала отключаем само устройство на уровне драйвера
            ОбъектСканер.DeviceEnabled = 0; // Или Ложь, в зависимости от версии драйвера
            
            // 2. Если используется старый драйвер Атол или ScanOPOS, 
            // иногда требуется перевести в режим OldVersion
            // ОбъектСканер.OldVersion = 0; 
            
            // 3. Обнуляем ссылку на объект
            ОбъектСканер = Неопределено;
        Исключение
            Сообщить("Ошибка при отключении сканера: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

Важный момент: если вы используете драйверы «Атол» старых версий (например, 6.х или 8.х), убедитесь, что в вашей версии нет метода Done(). Если он есть, его вызов перед обнулением объекта обязателен.

Решение 2. Переход на Native API компоненту

Библиотеки scanopos.dll и scaner1c.dll используют технологию COM, которая в современных операционных системах считается устаревшей и нестабильной в RDP-среде. Мы рекомендуем перейти на использование Native API компоненты от 1С (1C:BarCodeScanner).

Преимущества Native API:

  1. Работает напрямую в адресном пространстве 1С без регистрации в реестре Windows.
  2. Более корректно обрабатывает завершение сеанса и освобождение ресурсов.
  3. Автоматически подхватывается подсистемой БСП (Библиотека стандартных подсистем).

Для перехода проанализируем настройки торгового оборудования в вашей конфигурации. Если это «Управление торговлей 10.3», попробуйте обновить обработку обслуживания до последней версии, поддерживающей NativeApi.

Решение 3. Настройка параметров RDP и тайм-аутов

Если код корректен, но проблема сохраняется на Windows Server 2008, выясним, не блокирует ли порт сама служба RDS. Проанализируем настройки подключения в конфигурации RDP-клиента:

Решение 4. Диагностика с помощью утилиты Handle

Чтобы точно понять, какой процесс держит порт, воспользуемся системной утилитой Handle от Sysinternals. Запустите ее в командной строке на сервере:

handle.exe \Device\Serial

Проанализируем вывод. Если вы видите, что дескриптор порта удерживается процессом 1cv8.exe даже после закрытия обработки, значит, объект COM все еще «жив» в памяти. Если же порт держит системный процесс или rdpclip.exe, проблема на уровне операционной системы.

Решение 5. Альтернативный режим (Эмуляция клавиатуры)

Если борьба с виртуальными COM-портами в RDP не приносит успеха, рассмотрим вариант перевода сканера в режим Keyboard Emulation. В этом режиме сканер не занимает порт, а передает данные как обычный ввод с клавиатуры. Для 1С это потребует использования префиксов (например, # или F7), чтобы программа понимала, что ввод пришел со сканера, а не от пользователя.

Резюмируем: для стабильной работы в RDP на Windows Server 2008 лучше всего отказаться от старых COM-компонент в пользу Native API. Если это невозможно — всегда явно устанавливайте DeviceEnabled = 0 перед уничтожением объекта в 1С.

← На главную