Если с "Обычными формами" все несколько проще, и существует более одного решения по отключению пользователей, то с управляемыми, и на последних платформах 8.3 возникают различные проблемы.
Во-первых, добавляются веб-подключения.
Во-вторых, 8.3 сама решает, сколько Рабочих Процессов создать (не всегда можно знать заранее их количество).
В-третьих, в обработке предусмотрена ситуация, когда подключение сущестовало на момент запуска обработки, но уже отключилось (завершилось) на момент попытки его отключения.
Информация об этом запишется в лог-файл.
Запускать можно с любого ПК сети, откуда администрируется сервер. То есть это может быть как Windows-cервер, так и сервер с ОС Linux, просто в последнем случае соединения "рубятся" (и обработка запускается) с ПК из сети, а не с самого сервера.
Всегда существует возможность и создать регламентное задание, внеся " отключение пользователей " в конфигурацию, но я не преверженец этого метода.
По задумке, обработка используется в связке с Effector Saver, даже бесплатная версия которой весьма успешно снимает резервные копии с SQL в DT, и умеет хранить указанное количество копий (например, 30 штук). Разумеется, пользователь может снимать резервные копии любым иным способом (но нужна обработка для выгрузки именно в DT; SQL-копиям без разницы, но у них есть другие ограничения).
---
Запуск обработки предполагается скриптом подобного содержания, где
/nBackuper /p123 - запуск от имени пользователя Backuper с паролем 123,
/s127.0.0.1\uf2016 - обращение к локальному адресу, базе uf2016,
/execute E:\scripts\UserKill_v3.epf - запуск обработки UserKill_v3.epf , расположенной по указанному адресу.
echo запуск new_stop_Buh %Time% %Date% >> E:\scripts\log.txt
"C:\Program Files (x86)\1cv8\common\1cestart.exe" ENTERPRISE /s127.0.0.1\uf2016 /nBackuper /p123 /wa- /DisableStartupMessages /RunModeManagedApplication /execute E:\scripts\UserKill_v3.epf
---
Текст обработки по отключению пользователей.
Опять же, не забудьте сменить текст в строке РабПроц.AddAuthentication("Backuper", "123");
В принципе, можно получать логин и пароль из констант в конфигурации - вовсе не обязательно вписывать их в код.
&НаКлиенте
Процедура ПриОткрытии(Отказ)
текстош="";
текстош=ПриОткрытииНаСервере();
если текстош <> "" тогда
ФайлРегистрации = Новый ЗаписьТекста("E:\scripts\LogFile1c.txt", КодировкаТекста.ANSI, , Истина);
ФайлРегистрации.Записать(строка(текстош)+Символы.ПС);
ФайлРегистрации.Закрыть();
конецесли;
ЗавершитьРаботуСистемы(Ложь);
КонецПроцедуры
&НаСервере
функция ПриОткрытииНаСервере()
текстош="";
Если Найти(СтрокаСоединенияИнформационнойБазы(), "Srvr") > 0 Тогда
// серверный вариант
Поиск1 = Найти(СтрокаСоединенияИнформационнойБазы(), "Srvr=");
ПодстрокаПоиска = Сред(СтрокаСоединенияИнформационнойБазы(), Поиск1 + 6);
ИмяСервера = Лев(ПодстрокаПоиска, Найти(ПодстрокаПоиска, """") - 1);
// теперь ищем имя базы
Поиск1 = Найти(СтрокаСоединенияИнформационнойБазы(), "Ref=");
ПодстрокаПоиска = Сред(СтрокаСоединенияИнформационнойБазы(), Поиск1 + 5);
ИмяБазы = Лев(ПодстрокаПоиска, Найти(ПодстрокаПоиска, """") - 1);
Иначе
// для других способов подключения алгоритм не актуален
текстош=" Способ не актуален";
Возврат текстош;
КонецЕсли;
Коннектор = Новый COMОбъект("v83.COMConnector");
Агент = Коннектор.ConnectAgent(ИмяСервера);
Кластеры = Агент.GetClusters();
Для каждого Кластер из Кластеры Цикл
АдминистраторКластера = "Имя администратора кластера";
ПарольКластера = "Пароль администратора кластера";
//Агент.Authenticate(Кластер, АдминистраторКластера, ПарольКластера);
Агент.Authenticate(Кластер,,);
Процессы = Агент.GetWorkingProcesses(Кластер);
Для каждого Процесс из Процессы Цикл
Порт = Процесс.MainPort;
// теперь есть адрес и порт для подключения к рабочему процессу
попытка
РабПроц = Коннектор.ConnectWorkingProcess(ИмяСервера + ":" + СтрЗаменить(Порт, Символы.НПП, ""));
РабПроц.AddAuthentication("Backuper", "123");
ИнформационнаяБаза = "";
Базы = Агент.GetInfoBases(Кластер);
Для каждого База из Базы Цикл
Если База.Name = ИмяБазы Тогда
ИнформационнаяБаза = База;
Прервать;
КонецЕсли;
КонецЦикла;
Если ИнформационнаяБаза = "" Тогда
// база не найдена
КонецЕсли;
Сеансы = Агент.GetInfoBaseSessions(Кластер, ИнформационнаяБаза);
Для каждого Сеанс из Сеансы Цикл
Если нРег(Сеанс.AppID) = "backgroundjob" ИЛИ нРег(Сеанс.AppID) = "comconsole" Тогда
// если это сеансы com-приложения или фонового задания, то не отключаем
Продолжить;
КонецЕсли;
Если Сеанс.UserName = ИмяПользователя() Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
Агент.TerminateSession(Кластер, Сеанс);
Сообщить("Отключен сеанс "+строка(Сеанс.UserName));
КонецЦикла;
ИнформационнаяБаза2 = РабПроц.CreateInfoBaseInfo();
ИнформационнаяБаза2.Name = ИмяБазы;
СоединенияБазы = РабПроц.GetInfoBaseConnections(ИнформационнаяБаза2);
// Разорвать соединения клиентских приложений.
Для Каждого Соединение Из СоединенияБазы Цикл
Если нРег(Соединение.AppID) = "backgroundjob" ИЛИ нРег(Соединение.AppID) = "comconsole" Тогда
Продолжить;
КонецЕсли;
Если Соединение.UserName = ИмяПользователя() Тогда
// это текущий пользователь
Продолжить;
КонецЕсли;
РабПроц.Disconnect(Соединение);
КонецЦикла;
Исключение
текстош=текстош+" Ошибка при откл пользователей userkill " + строка(ИмяБазы)+ " "+строка(ТекущаяДата());
конецпопытки;
КонецЦикла;
КонецЦикла;
Сообщить("Завершается работа...");
Возврат текстош;
КонецФункции
!!! Разумеется, при первом запуске внешней обработки в последних релизах платформы - ее исполнение нужно "разрешить", так что, перед тем, как пустить в свободное плавание - пару раз протестируйте.