В процессе разработки на платформе 1С:Предприятие часто возникает задача программного мониторинга активности пользователей. Это может быть необходимо для выполнения регламентных работ, требующих монопольного доступа, или для построения отчетов по загруженности системы. Одним из наиболее гибких инструментов для решения этой задачи является использование COM-соединения. В данной статье мы разберем, как получить список пользователей, используя различные подходы в зависимости от того, нужен ли нам список всех зарегистрированных лиц или только тех, кто работает в базе в данный момент.
Прежде чем переходить к коду, давайте проанализируем важный нюанс, который часто вызывает путаницу у начинающих разработчиков. В 1С существует два принципиально разных понятия:
ПользователиИнформационнойБазы.Рассмотрим по шагам, как получить оба варианта данных через COM-объект.
Если ваша задача — просто выгрузить список всех существующих в базе пользователей (их имена, полные имена, роли), мы воспользуемся объектом V83.COMConnector для прямого подключения к базе. Рассмотрим пример кода:
СтрокаПодключения = "file='" + ПутьКБазе + "'; usr='" + ИмяПользователя + "'; pwd='" + Пароль + "';";
COMConnector = Новый COMОбъект("V83.COMConnector");
Попытка
ComConnection = COMConnector.Connect(СтрокаПодключения);
Сообщить("Соединение установлено успешно");
Исключение
Сообщить("Ошибка подключения: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Обращаемся к менеджеру пользователей через COM-соединение
ПользователиМассив = ComConnection.ПользователиИнформационнойБазы.ПолучитьПользователей();
Для Каждого ТекПользователь Из ПользователиМассив Цикл
Сообщить("Имя: " + ТекПользователь.Имя + " | Полное имя: " + ТекПользователь.ПолноеИмя);
КонецЦикла;
В данном примере мы используем метод ПолучитьПользователей(). Важно помнить, что при работе через COM свойства объектов могут возвращаться как специфические COM-объекты, поэтому при выводе данных лучше явно обращаться к примитивным типам (строкам, числам).
Если нам нужно узнать, кто находится в базе прямо сейчас, мы можем использовать метод ПолучитьСоединенияИнформационнойБазы(). Проанализируем ситуацию: этот метод возвращает массив объектов ОписаниеСоединения.
// Предполагаем, что ComConnection уже создано (см. предыдущий пример)
СписокСоединений = ComConnection.ПолучитьСоединенияИнформационнойБазы();
Для Каждого Соединение Из СписокСоединений Цикл
// В свойстве Пользователь объекта ОписаниеСоединения находится объект ПользовательИнформационнойБазы
ИмяПользователя = Соединение.Пользователь.Имя;
ИмяКомпьютера = Соединение.ИмяКомпьютера;
ВремяНачала = Соединение.ВремяНачала;
Сообщить("Пользователь: " + ИмяПользователя + " зашел с ПК: " + ИмяКомпьютера + " в " + ВремяНачала);
КонецЦикла;
Важное ограничение: В клиент-серверном варианте работы данный метод может отображать не все сеансы, а только те, которые видит текущий рабочий процесс, к которому вы подключились. Для получения гарантированно полного списка в серверной базе лучше использовать интерфейс администрирования кластера.
Рассмотрим более сложный, но надежный метод, который позволяет получить список всех сеансов без непосредственного входа в саму базу. Этот метод требует прав администратора кластера 1С.
Алгоритм действий следующий:
COMConnector.Разберем пример кода для реализации этой схемы:
COMConnector = Новый COMОбъект("V83.COMConnector");
// Подключаемся к агенту сервера (укажите имя вашего сервера)
ServerAgent = COMConnector.ConnectAgent("ИмяВашегоСервера");
// Получаем массив кластеров
Кластеры = ServerAgent.GetClusters();
Для Каждого Кластер Из Кластеры Цикл
// Аутентификация в кластере (если установлены логин/пароль администратора кластера)
ServerAgent.Authenticate(Кластер, "", "");
// Получаем рабочие процессы
РабочиеПроцессы = ServerAgent.GetWorkingProcesses(Кластер);
Для Каждого Процесс Из РабочиеПроцессы Цикл
// Подключаемся к рабочему процессу
СтрокаКоннектаПроцесса = Процесс.HostName + ":" + Формат(Процесс.MainPort, "ЧГ=0");
РабочийПроцессСоединение = COMConnector.ConnectWorkingProcess(СтрокаКоннектаПроцесса);
// Аутентификация в рабочем процессе
РабочийПроцессСоединение.AddAuthentication(АдминИБ, ПарольАдминаИБ);
// Получаем список информационных баз на этом процессе
Базы = РабочийПроцессСоединение.GetInfoBases();
Для Каждого База Из Базы Цикл
Если ВРег(База.Name) = ВРег("ИмяВашейБазыНаСервере") Тогда
// Получаем массив соединений
СоединенияБазы = РабочийПроцессСоединение.GetInfoBaseConnections(База);
Для Каждого ТекСоединение Из СоединенияБазы Цикл
Сообщить("Активный пользователь: " + ТекСоединение.UserName);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
При работе с COM-объектами 1С часто возникают технические сложности, которые стоит разобрать заранее:
comcntr.dll. Если сервер 1С 64-битный, убедитесь, что на машине, где выполняется код, зарегистрирована соответствующая компонента.regsvr32 "C:\Program Files\1cv8\8.3.X.XXXX\bin\comcntr.dll".GetInfoBaseSessions() вместо GetInfoBaseConnections(), так как сеанс более точно отражает логическую работу пользователя в системе.Выясним, какой метод выбрать именно вам. Если у вас файловая база или вам достаточно данных о пользователях изнутри самой базы — используйте Способ 2. Если вы строите серьезную систему мониторинга для большой серверной инфраструктуры — ваш выбор Способ 3, так как он позволяет видеть даже тех пользователей, которые "зависли" на уровне сервера приложений.
Используя приведенные примеры, вы сможете гибко управлять сеансами и получать актуальную информацию о состоянии вашей информационной системы в любой момент времени.