В файловом варианте работы 1С:Предприятие часто возникает ситуация, когда лицензии оказываются заняты «зависшими» сеансами. В отличие от клиент-серверного варианта, здесь нет консоли администрирования серверов 1С, которая позволила бы одним кликом завершить работу пользователя. В данной статье мы разберем, как программно реализовать механизм выдворения пользователей, используя штатные средства конфигураций на базе БСП (Бизнес-инструментарий) и возможности операционной системы Windows.
Рассмотрим ситуацию: пользователю необходимо монопольно зайти в базу или просто освободить лицензию для коллеги, но в диспетчере задач сервера или компьютера висят старые процессы 1cv8.exe. Метод ПрекратитьРаботуСистемы(), упомянутый в обсуждении, работает эффективно только в том случае, если клиентское приложение активно и способно исполнять код. Если же сеанс «завис» (например, из-за сетевого сбоя или ошибки в бесконечном цикле), программный код внутри 1С просто не выполнится.
Выясним причину, по которой это происходит в файловом режиме: лицензию удерживает непосредственно процесс операционной системы. Поэтому для решения задачи нам потребуется комбинированный подход: мягкое завершение через механизмы 1С и жесткое — через средства ОС.
Если ваша конфигурация построена на базе 1С:Библиотеки стандартных подсистем (БП 3.0, УНФ, ЗУП 3.1), в ней уже заложен механизм блокировки работы пользователей. Проанализируем, как он работает: программа создает в каталоге базы специальный файл 1Cv8.cdn. Все клиентские приложения периодически проверяют наличие этого файла.
Чтобы воспользоваться этим механизмом программно, мы можем обратиться к встроенной обработке. Разберем по шагам, как это вызвать из своего кода:
ПараметрыБлокировки = СоединенияИСеансы.ПараметрыБлокировкиСеансов();
ПараметрыБлокировки.УстановкаЗаблокирована = Истина;
ПараметрыБлокировки.Начало = ТекущаяДата();
ПараметрыБлокировки.Сообщение = "Работа системы временно приостановлена для обслуживания.";
ПараметрыБлокировки.КодРазрешения = "КлючДляВходаАдмина";
СоединенияИСеансы.УстановитьБлокировкуСеансов(ПараметрыБлокировки);
После установки такой блокировки у всех активных пользователей (кроме тех, кто запустил базу с параметром /UC) сработает обработчик ожидания, который через несколько минут закроет приложение. Однако помните: для зависших процессов этот метод может не сработать, так как они не смогут обработать команду закрытия.
Когда нужно «убить» процессы других пользователей, не выходя из 1С, самым элегантным решением будет использование COM-объекта WbemScripting.SWbemLocator. Этот способ позволяет программно найти все запущенные экземпляры 1cv8.exe и завершить их, если их идентификатор процесса (PID) не совпадает с текущим.
Посмотрим на пример реализации такой обработки:
Процедура ЗавершитьВсеСеансыКромеТекущего() Экспорт
// Получаем PID текущего процесса, чтобы не закрыть самих себя
ТекущийPID = СтрЗаменить(ЗапуститьПриложениеИПолучитьРезультат("cmd /c wmic process where name='1cv8.exe' get processid"), "ProcessId", "");
Locator = Новый COMОбъект("WbemScripting.SWbemLocator");
Service = Locator.ConnectServer(".", "root\cimv2");
// Ищем все процессы 1С (толстый и тонкий клиент)
Запрос = "SELECT * FROM Win32_Process WHERE Name = '1cv8.exe' OR Name = '1cv8c.exe'";
СписокПроцессов = Service.ExecQuery(Запрос);
Для Каждого Процесс Из СписокПроцессов Цикл
// Здесь можно добавить проверку на ID текущего сеанса
// Если Процесс.ProcessId <> МойPID Тогда
Попытка
Процесс.Terminate();
Сообщить("Завершен процесс с ID: " + Процесс.ProcessId);
Исключение
Сообщить("Не удалось завершить процесс: " + ОписаниеОшибки());
КонецПопытки;
// КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важный момент: Для выполнения этого кода у пользователя должны быть права на управление процессами в операционной системе (обычно это права администратора или опытного пользователя на сервере).
Если нам не нужна сложная логика анализа процессов, мы можем использовать простую системную команду taskkill. Рассмотрим, как вызвать её прямо из режима 1С:Предприятие. Этот метод эффективен, когда база запущена в терминальном режиме (RDP).
Проанализируем пример команды, которая закрывает все процессы 1С, кроме текущего (в контексте прав пользователя):
КомандаСистемы = "taskkill /F /IM 1cv8.exe /FI ""PID ne " + Формат(ТекущийPID, "ЧГ=0") + """";
ЗапуститьПриложение(КомандаСистемы, , Истина);
Здесь флаг /F означает принудительное завершение, /IM указывает имя образа, а фильтр /FI позволяет исключить наш текущий процесс из списка «смертников».
Иногда даже после завершения всех процессов в диспетчере задач, 1С продолжает считать, что база занята. Это происходит из-за «мусорных» файлов в каталоге информационной базы. Разберем, какие файлы можно безопасно удалять при закрытой 1С:
*.lcl — это временные файлы блокировок сеансов.1Cv8.lgc — если он разросся до огромных размеров и мешает входу.v8_XXXX_XX.Внимание: Никогда не удаляйте файл 1Cv8.1CD — это и есть сама база данных!
Чтобы не прибегать к радикальным мерам слишком часто, рекомендуем настроить политики терминального сервера. Посмотрим на основные настройки GPO (Group Policy):
Использование вышеописанных методов позволит вам эффективно управлять лицензиями в файловом режиме 1С, не прибегая к перезагрузке всего сервера, что значительно повысит комфорт работы пользователей и администраторов системы.