Разберем распространенную проблему в клиент-серверной архитектуре 1С:Предприятие: код для завершения активных сеансов, использующий COM-соединение, отлично работает при запуске из внешней обработки интерактивно, но «молчит» при выполнении в составе регламентного задания. При этом «Консоль заданий» может сообщать, что задание выполнено успешно, но фактически сеансы остаются висеть. Проанализируем ситуацию и выясним, почему так происходит и как это исправить.
Для начала рассмотрим программный код, который часто используется для этих целей. Автор использует объект v83.COMConnector для подключения к агенту сервера и перебора сеансов кластера. Рассмотрим основной фрагмент:
Процедура ЗакрытиеАктивныхСеансов() Экспорт
ПараметрыАдминистрированияИБ = УправлениеСоединениямиИБ.ПолучитьПараметрыАдминистрированияИБ();
Попытка
Сеансы = ПолучитьАктивныеСеансыИБ(ПараметрыАдминистрированияИБ);
Для каждого Сеанс Из Сеансы.Сеансы Цикл
// Разрываем соединение
Сеансы.АгентСервера.TerminateSession(Сеансы.КластерСерверов, Сеанс);
// ... запись в Журнал Регистрации
КонецЦикла;
Исключение
// ... обработка ошибки
КонецПопытки;
КонецПроцедуры
Проблема заключается в том, что когда этот код запускается во внешней обработке, он выполняется в контексте клиентского приложения (или в вашем сеансе на терминальном сервере). Когда же код попадает в регламентное задание, он выполняется на стороне сервера 1С в процессе rphost.exe. Здесь вступают в силу ограничения среды исполнения, прав доступа и разрядности систем.
Первым делом нам необходимо понять, на каком именно этапе прерывается выполнение. Поскольку регламентное задание не может вывести сообщение пользователю, мы должны использовать ЖурналРегистрации или запись в текстовый файл. Рассмотрим, как дополнить код для диагностики, согласно советам экспертов:
// Добавим контрольные точки в Журнал Регистрации
ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Информация, , , "Начало работы регламентного задания");
Попытка
COMСоединитель = Новый COMОбъект(ИмяCOMСоединителя);
ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Информация, , , "COM-объект успешно создан");
Исключение
ЗаписьЖурналаРегистрации("ЗавершениеСеансов", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка создания COM: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Если в журнале регистрации после запуска задания нет записи «COM-объект успешно создан», значит, проблема в регистрации компоненты comcntr.dll на сервере или в правах доступа к ней.
Выясним причину, связанную с «битностью» систем. Это самая частая причина неудач. Если у вас установлен 64-битный сервер 1С, то процесс rphost.exe является 64-разрядным. Для успешного вызова Новый COMОбъект("v83.COMConnector") в системе должна быть зарегистрирована 64-битная версия библиотеки comcntr.dll.
Зачастую при установке платформы регистрируется только 32-битная версия. Чтобы исправить это, выполните следующие действия на сервере, где установлен 1С:Предприятие:
C:\Program Files\1cv8\8.3.X.XXXX\bin).regsvr32 comcntr.dll.Важный момент: если сервер 64-битный, убедитесь, что вы регистрируете библиотеку именно из папки Program Files, а не Program Files (x86).
Проанализируем ситуацию с правами. Регламентное задание выполняется под учетной записью службы сервера 1С (обычно это USR1CV8). У этой учетной записи по умолчанию крайне ограниченные права в операционной системе. Она может не иметь прав на запуск DCOM-объектов или на сетевое взаимодействие с другим сервером (если агент сервера находится на другой машине).
Наиболее надежный способ решить проблемы с правами и разрядностью — настроить Приложение COM+:
comcntr.dll.Этот метод заставляет систему запускать COM-объект в отдельном процессе dllhost.exe под указанной вами учетной записью, что снимает ограничения прав USR1CV8.
Рассмотрим более современный подход. Использование COM-соединителя считается устаревшим методом администрирования. В современных версиях платформы (8.3.x) для управления сеансами рекомендуется использовать программный интерфейс администрирования (RAS/RAC) или средства Библиотеки Стандартных Подсистем (БСП).
Если в вашей конфигурации используется БСП, вместо написания собственного кода через COM, лучше воспользоваться готовым методом модуля СоединенияИБ. Это избавит вас от проблем с регистрацией DLL и разрядностью, так как взаимодействие происходит по протоколу TCP/IP (порт 1545 по умолчанию).
Пример логики без COM, используя стандартные механизмы:
ПараметрыБлокировки = УправлениеСоединениямиИБ.ПараметрыБлокировкиСеансов();
ПараметрыБлокировки.УстановкаЗаблокирована = Истина;
ПараметрыБлокировки.Сообщение = "Выполняются регламентные работы.";
УправлениеСоединениямиИБ.УстановитьБлокировкуСеансов(ПараметрыБлокировки);
Этот метод не просто «убивает» сеансы, а корректно завершает работу пользователей, используя штатные механизмы платформы.
Проанализируем еще один нюанс в коде автора. При вызове TerminateSession из регламентного задания важно убедиться, что задание не пытается завершить само себя. Хотя в коде есть проверка Если НомерТекущегоСеанса <> Сеанс.SessionID, при работе через COM-соединение идентификатор текущего сеанса может определяться некорректно или относиться к самому COM-соединению.
Также обратите внимание на определение порта кластера. Строка НомерПортаКластера = COMСоединитель.RMngrPortDefault может возвращать пустое значение в серверном контексте. Мы рекомендуем явно указывать порты (1540, 1541), если они отличаются от стандартных, или брать их напрямую из параметров строки соединения информационной базы.
Подведем итог: для исправления работы регламентного задания нам нужно либо обеспечить регистрацию 64-битной версии COM-компоненты на сервере, либо настроить приложение COM+ для обхода ограничений прав доступа, либо (что предпочтительнее) перейти на использование стандартных методов БСП или RAS, которые не зависят от COM-технологий Windows.