Проблема «зависших» пользователей в 1С:Предприятии 7.7 знакома каждому администратору. Пользователи часто забывают закрывать программу, оставляя терминальные сессии активными, что мешает проведению ночного архивирования, обновлению конфигурации или монопольному обслуживанию базы данных. В этой статье мы подробно разберем, как организовать корректный «выгон» пользователей, избежав при этом долгой переиндексации таблиц.
Это один из самых универсальных и надежных способов, так как он не требует внесения изменений в структуру метаданных (константы, справочники) и легко переносится между разными конфигурациями. Суть метода заключается в том, что программа периодически проверяет наличие определенного файла в каталоге базы данных. Если файл найден — инициируется выход.
Рассмотрим алгоритм реализации. В глобальном модуле в процедуре ПриНачалеРаботыСистемы необходимо запустить обработку ожидания. Проанализируем пример кода:
Процедура ПриНачалеРаботыСистемы()
// Устанавливаем проверку раз в 60 секунд
ОбработкаОжидания("глПроверитьБлокировку", 60);
КонецПроцедуры
Процедура глПроверитьБлокировку()
// Путь к файлу-флагу в каталоге базы
ФайлФлага = КаталогИБ() + "exit.txt";
Если ФС.СуществуетФайл(ФайлФлага) = 1 Тогда
// Можно добавить предупреждение перед закрытием
Сообщить("Внимание! База будет закрыта через 30 секунд для обслуживания.");
ЗавершитьРаботуСистемы(0);
КонецЕсли;
КонецПроцедуры
Преимущества: метод работает корректно, вызывая штатное завершение работы, что предотвращает появление ошибки «Индексы не актуальны» при следующем запуске. Чтобы закрыть всех пользователей, вам достаточно создать пустой текстовый файл exit.txt в папке с базой.
Основная проблема стандартной команды ЗавершитьРаботуСистемы(0) в 1С 7.7 заключается в том, что она бессильна, если у пользователя открыто модальное окно (например, вопрос «Сохранить изменения?» или предупреждение). Проанализируем ситуацию: таймер срабатывает, но программа «висит» на вопросе системы.
Для решения этой задачи мы можем использовать объект WScript.Shell, который имитирует нажатие клавиш. Разберем по шагам, как это реализовать в глобальном модуле:
Перем НеудачнаяПопыткаЗакрытия; // Глобальная переменная
Процедура глАвтоЗакрытие()
Если ФС.СуществуетФайл(КаталогИБ() + "exit.txt") = 1 Тогда
// Если попытки уже были, пробуем "пробить" модальные окна
Если НеудачнаяПопыткаЗакрытия > 0 Тогда
WShell = СоздатьОбъект("WScript.Shell");
WShell.SendKeys("{ESC}"); // Закрываем текущее окно
WShell.SendKeys("%{F4}"); // Посылаем команду Alt+F4
КонецЕсли;
НеудачнаяПопыткаЗакрытия = НеудачнаяПопыткаЗакрытия + 1;
ЗавершитьРаботуСистемы(0);
Иначе
НеудачнаяПопыткаЗакрытия = 0;
КонецЕсли;
КонецПроцедуры
Такой подход позволяет программно нажать клавишу Escape, чтобы закрыть мешающее диалоговое окно, а затем повторно попытаться завершить работу системы.
Если ваша задача — выгонять не всех сразу, а только тех, кто не проявляет активности более часа, нам потребуется внешняя компонента, умеющая отслеживать движения мыши и нажатия клавиш. Часто для этого используется NoSlip.dll или функционал из состава FormEx.dll.
Выясним, как это работает. Компонента предоставляет счетчик времени с момента последнего ввода пользователя. Пример кода с использованием функции GetLastInputInfo:
Процедура глПроверкаПростоя()
// Получаем время бездействия в секундах
ВремяБездействия = глНеСпать.GetLastInputInfo();
// Если пользователь не активен более 3600 секунд (1 час)
Если ВремяБездействия > 3600 Тогда
ЗавершитьРаботуСистемы(0);
КонецЕсли;
КонецПроцедуры
Этот метод особенно полезен для освобождения лицензий и ресурсов сервера в течение рабочего дня.
Если пользователи работают через RDP (удаленный рабочий стол), многие задачи можно решить на уровне операционной системы. Рассмотрим настройки сеансов на сервере:
1cv7.exe.taskkill /F /IM 1cv7.exe. Однако помните, что это аварийное завершение, которое гарантированно вызовет требование переиндексации при запуске DBF-версии базы.При реализации любого из методов «выгона» важно учитывать следующие моменты:
1. Информирование: Всегда давайте пользователям шанс сохранить данные. Перед закрытием выводите Предупреждение с таймаутом, чтобы человек, случайно отошедший от рабочего места, мог нажать «Отмена».
2. Исключения для администраторов: В коде проверки флага всегда добавляйте проверку по имени пользователя. Программист или администратор должны иметь возможность находиться в базе даже при включенной блокировке для проведения работ.
3. Работа в SQL-версии: Если вы используете версию 1С для MS SQL Server, проблему «зависших» соединений можно решать через SQL Management Studio, убивая процессы (SPID) непосредственно на сервере базы данных. Это не требует переиндексации, так как за целостность данных отвечает SQL-сервер.
Подводя итог, наиболее сбалансированным решением для 1С 7.7 является комбинация таймера в глобальном модуле, проверяющего текстовый файл-флаг, и использование WScript.Shell для обработки забытых пользователями открытых окон. Это гарантирует корректное освобождение базы в 99% случаев.