Поставлено ТЗ написания как можно более простого метода, чтобы "мягко" отключать пользователей. Базы как клиент-серверные, так и файловые. И отключать надо по команде, а не каждую сессию отдельно руками.
Концепция решения "мягкого" отключения следующая - пользователь должен "сам" завершить свою работу. Иными словами необходимо дать клиенту понять, что необходимо завершить работу. Вариаций можно добавить сколько угодно.
Для этого была написана админовская часть, использующая некую табличную часть сеансов, получающая сеансы с АГЕНТА для клиент-серверных баз, так и с файловых баз, используя механизм COM(медленный) или HTTP-сервисы(быстрый, предпочтительно), с функцией отключения нужного сеанса:
Процедура ДатьЗаданиеНаОтключениеСеансовИБ(ИБ, ИмяПользователя, НомерСеанса, ИмяПриложения, Компьютер, СообщениеПользователю = "", ТаймАут=10) Экспорт
// Сеанс.ИмяПриложения
//1CV8 - идентификатор приложения 1С:Предприятие в режиме запуска "Толстый клиент";
//1CV8C - идентификатор приложения 1С:Предприятие в режиме запуска "Тонкий клиент";
//WebClient - идентификатор приложения 1С:Предприятие в режиме запуска "Веб-клиент";
//Designer - идентификатор приложения Конфигуратор;
//COMConnection - идентификатор сессии внешнего соединения 1С:Предприятия через COM;
//WSConnection - идентификатор сессии Web-сервиса;
//BackgroundJob - идентификатор сессии обработки заданий;
//SystemBackgroundJob - идентификатор системного фонового задания;
//SrvrConsole - идентификатор сессии консоли кластера;
//COMConsole - идентификатор административной сессии внешнего соединения;
//JobScheduler - идентификатор сессии планировщика заданий;
//Debugger - идентификатор сессии отладчика;
//OpenIDProvider - провайдер OpenID;
//RAS - идентификатор сервера администрирования.
Если ИмяПриложения = "1CV8" или ИмяПриложения = "1CV8C" или ИмяПриложения = "WebClient" или ИмяПриложения = "Толстый клиент" или ИмяПриложения = "Тонкий клиент" или ИмяПриложения = "Веб-клиент" Тогда
КлючОбъекта = "ЗавершениеРаботы";
КлючНастроек = СтрЗаменить(Строка(НомерСеанса), Символы.НПП,"");
Настройки = ИБ.NewObject("Структура");
Настройки.Вставить("Пользователь", ИмяПользователя);
Настройки.Вставить("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь.Наименование);
Настройки.Вставить("Компьютер", Компьютер);
Настройки.Вставить("Сеанс", НомерСеанса);
Настройки.Вставить("ДатаИнициацииОтключения", ТекущаяДата());
Настройки.Вставить("ТаймАут", ТаймАут);
Если НЕ СообщениеПользователю = "" тогда
Настройки.Вставить("РежимОтключения", 2);// 0 - отключение без предупреждения, 1 - вывести с предупреждением , 2 - просто сообщение
Настройки.Вставить("СообщениеПользователю", СообщениеПользователю);
Иначе
Настройки.Вставить("РежимОтключения", 1);// 0 - отключение без предупреждения, 1 - вывести с предупреждением
Настройки.Вставить("СообщениеПользователю", "Сообщение от Админа: ""Просьба выйти из базы для выполнения архивации""");
КонецЕсли;
ОписаниеНастроек = "Отключение пользователя по запросу администратора";
ИБ.ХранилищеОбщихНастроек.Сохранить(КлючОбъекта, КлючНастроек, Настройки, ОписаниеНастроек, ИмяПользователя);
КонецЕсли;
КонецПроцедуры
Поскольку почти все клиентские базы стоят на поддержке без возможности вносить изменения, то было написано расширение. В нем присутствует функция оценки задания на отключение. Отключается только необходимый пользователь. По сути дела, решение принимает клиентская часть - "Если МНЕ задание на завершение работы, то будет предпринята попытка отключения". Ниже сама функция отключения
Функция КонтрольЗавершенияРаботы() Экспорт
НомерСеанса = ЗРП_ОбщийМодульСервер.ПолучитьНомерСеанса();
НачалоРаботы = ЗРП_ОбщийМодульСервер.ПолучитьдатуСеанса(НомерСеанса);
СтруктураПараметров = ЗРП_ОбщийМодульСервер.ЗагрузитьХранилищеОбщихНастроек("ЗавершениеРаботы", СтрЗаменить(Строка(НомерСеанса),Символы.НПП,""), ИмяПользователя());
Если НЕ СтруктураПараметров = Неопределено Тогда
Если НЕ ЗРП_ОбщийМодульСервер.ЗапущенКонфигуратор() Тогда
Если НомерСеанса = СтруктураПараметров.Сеанс Тогда
ЗРП_ОбщийМодульСервер.УдалитьХранилищеОбщихНастроек("ЗавершениеРаботы", СтрЗаменить(Строка(НомерСеанса),Символы.НПП,""), ИмяПользователя());
Попытка
Если СтруктураПараметров.ДатаИнициацииОтключения > НачалоРаботы Тогда // если пользователь успел выйти до команды
Если СтруктураПараметров.РежимОтключения = 0 Тогда // безусловное завершение без вопросов
ЗавершитьРаботуСистемы(Ложь);
ИначеЕсли СтруктураПараметров.РежимОтключения = 1 Тогда // только сообщение с описанием того кто выдал задание на закрытие
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЗРП_ОбщийМодульКлиент);
ПоказатьПредупреждение(Оповещение, СтрЗаменить(СтруктураПараметров.СообщениеПользователю, "%", СтруктураПараметров.ТекущийПользователь), СтруктураПараметров.ТаймАут);
ИначеЕсли СтруктураПараметров.РежимОтключения = 2 Тогда // выдача вопроса с интерактивным выбором ЗАКРЫТЬ или НЕТ
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияВопроса", ЗРП_ОбщийМодульКлиент);
Кнопки = Новый СписокЗначений;
Кнопки.Добавить(КодВозвратаДиалога.ОК, "Завершить");
Кнопки.Добавить(КодВозвратаДиалога.Отмена, "Отмена");
ПоказатьВопрос(Оповещение, СтрЗаменить(СтруктураПараметров.СообщениеПользователю, "%", СтруктураПараметров.ТекущийПользователь), Кнопки, СтруктураПараметров.ТаймАут, , "Завершение работы системы");
ИначеЕсли СтруктураПараметров.РежимОтключения = 3 Тогда // только сообщение
Предупреждение(СтруктураПараметров.СообщениеПользователю, СтруктураПараметров.ТаймАут);
КонецЕсли;
КонецЕсли;
Исключение
ЗРП_ОбщийМодульСервер.ЗЖР("ЗавершениеРаботыПользователей.КонтрольЗавершенияРаботы()", "Ошибка",,ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецФункции
Расширение на данный момент работоспособно на версии ЗУП 3.1.11.133, БУХ 3.0.73.60, КА2 2.4.7.141/3.2.23.3(БИТфинанс). Поскольку не использовалось БСП, то и проблем с библиотекой тоже нет.
Остались две проблемы:
1. Разрешимая - условие совместимости, меняемое при обновлении, которое можно исправить в любой момент;
2. Не решённая - если на главном окне вылезло окно с вопросом, блокирующим весь интерфейс, ожидающего интерактивного принятия решения. Поиск решения ведётся.
P.S. Сильно прошу палками не кидать. Любые реальные ссылки будут восприняты с благодарностью.