Почему регламентное задание не закрывает сеансы пользователей через COM-соединение?

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

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

Анализ исходного кода и проблемы контекста

Для начала рассмотрим программный код, который часто используется для этих целей. Автор использует объект v83.COMConnector для подключения к агенту сервера и перебора сеансов кластера. Рассмотрим основной фрагмент:


Процедура ЗакрытиеАктивныхСеансов() Экспорт
    ПараметрыАдминистрированияИБ = УправлениеСоединениямиИБ.ПолучитьПараметрыАдминистрированияИБ();
    Попытка
        Сеансы = ПолучитьАктивныеСеансыИБ(ПараметрыАдминистрированияИБ);
        Для каждого Сеанс Из Сеансы.Сеансы Цикл
            // Разрываем соединение
            Сеансы.АгентСервера.TerminateSession(Сеансы.КластерСерверов, Сеанс);
            // ... запись в Журнал Регистрации
        КонецЦикла;
    Исключение
        // ... обработка ошибки
    КонецПопытки;
КонецПроцедуры

Проблема заключается в том, что когда этот код запускается во внешней обработке, он выполняется в контексте клиентского приложения (или в вашем сеансе на терминальном сервере). Когда же код попадает в регламентное задание, он выполняется на стороне сервера 1С в процессе rphost.exe. Здесь вступают в силу ограничения среды исполнения, прав доступа и разрядности систем.

Шаг 1. Диагностика через расширенное логирование

Первым делом нам необходимо понять, на каком именно этапе прерывается выполнение. Поскольку регламентное задание не может вывести сообщение пользователю, мы должны использовать ЖурналРегистрации или запись в текстовый файл. Рассмотрим, как дополнить код для диагностики, согласно советам экспертов:


// Добавим контрольные точки в Журнал Регистрации
ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Информация, , , "Начало работы регламентного задания");
Попытка
    COMСоединитель = Новый COMОбъект(ИмяCOMСоединителя);
    ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Информация, , , "COM-объект успешно создан");
Исключение
    ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка создания COM: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Если в журнале регистрации после запуска задания нет записи «COM-объект успешно создан», значит, проблема в регистрации компоненты comcntr.dll на сервере или в правах доступа к ней.

Шаг 2. Разрядность сервера и регистрация COM-компоненты

Выясним причину, связанную с «битностью» систем. Это самая частая причина неудач. Если у вас установлен 64-битный сервер 1С, то процесс rphost.exe является 64-разрядным. Для успешного вызова Новый COMОбъект("v83.COMConnector") в системе должна быть зарегистрирована 64-битная версия библиотеки comcntr.dll.

Зачастую при установке платформы регистрируется только 32-битная версия. Чтобы исправить это, выполните следующие действия на сервере, где установлен 1С:Предприятие:

  1. Запустите командную строку от имени администратора.
  2. Перейдите в каталог установленной платформы (например, C:\Program Files\1cv8\8.3.X.XXXX\bin).
  3. Выполните команду: regsvr32 comcntr.dll.

Важный момент: если сервер 64-битный, убедитесь, что вы регистрируете библиотеку именно из папки Program Files, а не Program Files (x86).

Шаг 3. Настройка прав доступа и использование COM+

Проанализируем ситуацию с правами. Регламентное задание выполняется под учетной записью службы сервера 1С (обычно это USR1CV8). У этой учетной записи по умолчанию крайне ограниченные права в операционной системе. Она может не иметь прав на запуск DCOM-объектов или на сетевое взаимодействие с другим сервером (если агент сервера находится на другой машине).

Наиболее надежный способ решить проблемы с правами и разрядностью — настроить Приложение COM+:

  1. Откройте «Службы компонентов» (Component Services) в администрировании Windows.
  2. Создайте новое пустое приложение COM+ (например, с именем "1C_COM_Connector").
  3. В свойствах приложения на закладке «Удостоверение» (Identity) укажите пользователя с правами локального администратора (или специально созданную учетную запись с достаточными правами).
  4. Внутри приложения перейдите в ветку «Компоненты» и добавьте новый компонент, указав путь к comcntr.dll.

Этот метод заставляет систему запускать COM-объект в отдельном процессе dllhost.exe под указанной вами учетной записью, что снимает ограничения прав USR1CV8.

Шаг 4. Использование альтернативного метода (RAS/RAC)

Рассмотрим более современный подход. Использование COM-соединителя считается устаревшим методом администрирования. В современных версиях платформы (8.3.x) для управления сеансами рекомендуется использовать программный интерфейс администрирования (RAS/RAC) или средства Библиотеки Стандартных Подсистем (БСП).

Если в вашей конфигурации используется БСП, вместо написания собственного кода через COM, лучше воспользоваться готовым методом модуля СоединенияИБ. Это избавит вас от проблем с регистрацией DLL и разрядностью, так как взаимодействие происходит по протоколу TCP/IP (порт 1545 по умолчанию).

Пример логики без COM, используя стандартные механизмы:


ПараметрыБлокировки = УправлениеСоединениямиИБ.ПараметрыБлокировкиСеансов();
ПараметрыБлокировки.УстановкаЗаблокирована = Истина;
ПараметрыБлокировки.Сообщение = "Выполняются регламентные работы.";
УправлениеСоединениямиИБ.УстановитьБлокировкуСеансов(ПараметрыБлокировки);

Этот метод не просто «убивает» сеансы, а корректно завершает работу пользователей, используя штатные механизмы платформы.

Особенности метода TerminateSession

Проанализируем еще один нюанс в коде автора. При вызове TerminateSession из регламентного задания важно убедиться, что задание не пытается завершить само себя. Хотя в коде есть проверка Если НомерТекущегоСеанса <> Сеанс.SessionID, при работе через COM-соединение идентификатор текущего сеанса может определяться некорректно или относиться к самому COM-соединению.

Также обратите внимание на определение порта кластера. Строка НомерПортаКластера = COMСоединитель.RMngrPortDefault может возвращать пустое значение в серверном контексте. Мы рекомендуем явно указывать порты (1540, 1541), если они отличаются от стандартных, или брать их напрямую из параметров строки соединения информационной базы.

Подведем итог: для исправления работы регламентного задания нам нужно либо обеспечить регистрацию 64-битной версии COM-компоненты на сервере, либо настроить приложение COM+ для обхода ограничений прав доступа, либо (что предпочтительнее) перейти на использование стандартных методов БСП или RAS, которые не зависят от COM-технологий Windows.

← На главную