Как принудительно завершить сеансы пользователей в файловой базе 1С для освобождения лицензий?

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

В файловом варианте работы 1С:Предприятие часто возникает ситуация, когда лицензии оказываются заняты «зависшими» сеансами. В отличие от клиент-серверного варианта, здесь нет консоли администрирования серверов 1С, которая позволила бы одним кликом завершить работу пользователя. В данной статье мы разберем, как программно реализовать механизм выдворения пользователей, используя штатные средства конфигураций на базе БСП (Бизнес-инструментарий) и возможности операционной системы Windows.

Анализ проблемы: почему стандартные методы не всегда помогают

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

Выясним причину, по которой это происходит в файловом режиме: лицензию удерживает непосредственно процесс операционной системы. Поэтому для решения задачи нам потребуется комбинированный подход: мягкое завершение через механизмы 1С и жесткое — через средства ОС.

Способ 1: Использование штатной блокировки соединений (БСП)

Если ваша конфигурация построена на базе 1С:Библиотеки стандартных подсистем (БП 3.0, УНФ, ЗУП 3.1), в ней уже заложен механизм блокировки работы пользователей. Проанализируем, как он работает: программа создает в каталоге базы специальный файл 1Cv8.cdn. Все клиентские приложения периодически проверяют наличие этого файла.

Чтобы воспользоваться этим механизмом программно, мы можем обратиться к встроенной обработке. Разберем по шагам, как это вызвать из своего кода:


ПараметрыБлокировки = СоединенияИСеансы.ПараметрыБлокировкиСеансов();
ПараметрыБлокировки.УстановкаЗаблокирована = Истина;
ПараметрыБлокировки.Начало = ТекущаяДата();
ПараметрыБлокировки.Сообщение = "Работа системы временно приостановлена для обслуживания.";
ПараметрыБлокировки.КодРазрешения = "КлючДляВходаАдмина";

СоединенияИСеансы.УстановитьБлокировкуСеансов(ПараметрыБлокировки);

После установки такой блокировки у всех активных пользователей (кроме тех, кто запустил базу с параметром /UC) сработает обработчик ожидания, который через несколько минут закроет приложение. Однако помните: для зависших процессов этот метод может не сработать, так как они не смогут обработать команду закрытия.

Способ 2: Принудительное завершение через WMI (Windows Management Instrumentation)

Когда нужно «убить» процессы других пользователей, не выходя из 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);
           Исключение
               Сообщить("Не удалось завершить процесс: " + ОписаниеОшибки());
           КонецПопытки;
        // КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важный момент: Для выполнения этого кода у пользователя должны быть права на управление процессами в операционной системе (обычно это права администратора или опытного пользователя на сервере).

Способ 3: Командная строка и утилита Taskkill

Если нам не нужна сложная логика анализа процессов, мы можем использовать простую системную команду taskkill. Рассмотрим, как вызвать её прямо из режима 1С:Предприятие. Этот метод эффективен, когда база запущена в терминальном режиме (RDP).

Проанализируем пример команды, которая закрывает все процессы 1С, кроме текущего (в контексте прав пользователя):


КомандаСистемы = "taskkill /F /IM 1cv8.exe /FI ""PID ne " + Формат(ТекущийPID, "ЧГ=0") + """";
ЗапуститьПриложение(КомандаСистемы, , Истина);

Здесь флаг /F означает принудительное завершение, /IM указывает имя образа, а фильтр /FI позволяет исключить наш текущий процесс из списка «смертников».

Способ 4: Очистка файлов блокировок вручную

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

  1. Файлы с расширением *.lcl — это временные файлы блокировок сеансов.
  2. Файл 1Cv8.lgc — если он разросся до огромных размеров и мешает входу.
  3. Временные папки вида v8_XXXX_XX.

Внимание: Никогда не удаляйте файл 1Cv8.1CD — это и есть сама база данных!

Рекомендации по предотвращению «зависаний»

Чтобы не прибегать к радикальным мерам слишком часто, рекомендуем настроить политики терминального сервера. Посмотрим на основные настройки GPO (Group Policy):

Использование вышеописанных методов позволит вам эффективно управлять лицензиями в файловом режиме 1С, не прибегая к перезагрузке всего сервера, что значительно повысит комфорт работы пользователей и администраторов системы.

← На главную