У клиента возникла задача. По соображениям безопасности нужно было проверять, запущена ли постоянно 1с у сотрудников в различных территориально удаленных подразделениях.
Для решения на компьютерах сотрудников я запускал скрипт, который создает файл в каталоге локальной VPN-сети, а в центре периодически запускал проверку наличия таких файлов. Делюсь опытом.
При отсутствии отклика от 1С компьютера в течение 20 минут должно формироваться почтовое извещение.
Повторно такое извещение должно отправляться только через час.
Извещения должны приходить только в рабочее время работы сотрудников, для каждого компьютера оно разное.
В начале дня не должно быть ложных тревог, должен быть некоторый задел.
Если компьютер начал работу после извещения, об этом должно тоже приходить извещение.
Для семафоров работы 1с у сотрудников я выделил в локальной сети общедоступный каталог. Флажки сделал в виде файлов, имя которых состояло из названия компьютеров:
Учитывая, что нужно хранить информацию о последнем извещении, решено было ее хранить в каталоге базы в отдельном файле check-settings.txt, чтобы не напрягать базу лишними операциями чтения и записи.
На компьютерах сотрудников периодически, раз в 3 минуты, выполнялся код вида:
ИмяФайла = "\\192.168.5.210\1c_obmen\here\" + СокрЛП(ИмяКомпьютера()) + ".xml";
Ф = Новый ТекстовыйДокумент();
Ф.Записать(ИмяФайла);
В центре периодически выполнялся код вида:
//Пути, настройки
ИмяКаталогаПроверок = "c:\1c_obmen\here\";
ФайлСохраненияНастроек = ФРАНЧ.ПолучитьКаталогБазы() + "\check-settings.txt";
КоличествоМинутДляИзвещения = 20;
КоличествоМинутДляПовторногоИзвещения = 60;
КоличествоМинутЗащитыОтСтартаКомпа = 45; //45 минут с момента старта компа ждем, не работаем
ИсхПолучатели = "boss@office.ru, support@office.ru, security@office.ru";
//Восстанавливаем из файла список последних оповещений
Попытка
Т = Новый ТекстовыйДокумент();
Т.Прочитать(ФайлСохраненияНастроек);
СтруктураНастроек = ЗначениеИзСтрокиВнутр(Т.ПолучитьТекст());
Исключение
СтруктураНастроек = Новый Структура("Компы", Новый ТаблицаЗначений());
СтруктураНастроек.Компы.Колонки.Добавить("Комп");
СтруктураНастроек.Компы.Колонки.Добавить("ДатаПоследнегоИзвещения");
СтруктураНастроек.Вставить("ДатаПоследнейПроверки", '00010101');
КонецПопытки;
//Получаем список компов, от которых есть отзывы на сервере
ТекЗадача = Справочники._ЗадачиПоРасписанию.НайтиПоКоду("ПЭПР1СРАБ");
З = Новый Запрос(
"ВЫБРАТЬ
| _ЗадачиПоРасписаниюМеста.Комп.Ссылка КАК Ссылка,
| _ЗадачиПоРасписаниюМеста.Комп.Код КАК Код
|ИЗ
| Справочник._ЗадачиПоРасписанию.Места КАК _ЗадачиПоРасписаниюМеста ГДЕ Ссылка = &ТекЗадача");
З.УстановитьПараметр("ТекЗадача", ТекЗадача);
Сообщить(ТекЗадача);
ТЗ = З.Выполнить().Выгрузить();
//Перебираем компы
Для Каждого Строка ИЗ ТЗ Цикл
ТекКомп = Строка.Ссылка;
//Проверяем, что текущее время подпадает под график работы сотрудника на компе
СтруктураДанныхКомпа = _УчетРабочегоВремени.ПолучитьДанныеПоУчетуРабочегоВремениНаДату(ТекущаяДата(), ТекКомп);
ВремяНачалаРаботыКомпа = СтруктураДанныхКомп.ВремяНачалаРаботы;
ВремяОкончанияРаботыКомпа = СтруктураДанныхКомпа.ВремяОкончанияРаботы;
Если НЕ ЗначениеЗаполнено(ВремяНачалаРаботыКомпа) ИЛИ НЕ ЗначениеЗаполнено(ВремяОкончанияРаботыКомпа) Тогда
Продолжить;
КонецЕсли;
Сейчас = ТекущаяДата();
ВремяСейчас = Дата(1, 1, 1, Час(Сейчас), Минута(Сейчас), Секунда(Сейчас));
//Если комп еще не работает, не извещать (оставляем небольшой задел при старте компа)...
Если ВремяСейчас < (ВремяНачалаРаботыКомпа + КоличествоМинутЗащитыОтСтартаКомпа * 60) ИЛИ ВремяСейчас > ВремяОкончанияРаботыКомпа Тогда
Продолжить;
КонецЕсли;
//Проверяем извещения
ТекКод = СокрЛП(Строка.Код);
Ф = Новый Файл(ИмяКаталогаПроверок + "\" + ТекКод + ".xml");
Если НЕ Ф.Существует() Тогда
ДатаПроверки = '00010101';
Иначе
ДатаПроверки = Ф.ПолучитьВремяИзменения();
КонецЕсли;
//Сообщить("" + Строка.Ссылка + ": " + ДатаПроверки );
Получатели = ИсхПолучатели;
//Получатели = Получатели + "," + ТекКомп.ЭлектроннаяПочта;
Получатели = Получатели + "," + ФРАНЧ.ПолучитьПочтовыеАдресаРуководителейСотрудников(ТекКомп);
Получатели = ФРАНЧ.ДатьУникальныеПочтовыеАдреса(Получатели);
ОтправлятьПисьмо = ложь;
//Получаем строку с информацией о компе
ИскСтрока = СтруктураНастроек.Компы.Найти(Строка.Ссылка, "Комп");
ДатаПоследнегоИзвещения = '00010101';
Если ИскСтрока = Неопределено Тогда
ИскСтрока = СтруктураНастроек.Компы.Добавить();
ИскСтрока.Комп = Строка.Ссылка;
ИскСтрока.ДатаПоследнегоИзвещения = '00010101';
КонецЕсли;
//Получаем дату последнего извещения. Если это не сегодняшняя дата, сбрасываем ее...
Если НачалоДня(ИскСтрока.ДатаПоследнегоИзвещения) <> НачалоДня(ТекущаяДата()) Тогда
ИскСтрока.ДатаПоследнегоИзвещения = '00010101';
КонецЕсли;
ДатаПоследнегоИзвещения = ИскСтрока.ДатаПоследнегоИзвещения;
//Если проверка не пройдена, т.е. комп не доложился...
Если ТекущаяДата() - ДатаПроверки > КоличествоМинутДляИзвещения * 60 Тогда
//Нужно ли извещать
//Если ранее не извещали или прошло нужное количество минут
Извещать = НЕ ЗначениеЗаполнено(ДатаПоследнегоИзвещения) ИЛИ ТекущаяДата() - ДатаПоследнегоИзвещения > КоличествоМинутДляПовторногоИзвещения * 60;
Если Извещать Тогда
//Извещаем
ИскСтрока.ДатаПоследнегоИзвещения = ТекущаяДата();
//Формируем письмо
Тема = "Не запущена база 1с на компе: " + Строка.Ссылка + " Нет подтверждения " + ?(НЕ ЗначениеЗаполнено(ДатаПроверки), "совсем", "" + Цел((ТекущаяДата() - ДатаПроверки) / 60) + " минут") + ".";
Тело = Тема;
Если ЗначениеЗаполнено(ДатаПоследнегоИзвещения) Тогда
Тело = Тело + Символы.ПС + "Дата последней активности компа: " + ?(НЕ ЗначениеЗаполнено(ДатаПроверки), " не указана", ДатаПроверки);
Тело = Тело + Символы.ПС + "Дата последнего извещения: " + ДатаПоследнегоИзвещения;
КонецЕсли;
//Нужно отправлять письмо
ОтправлятьПисьмо = истина;
КонецЕсли;
Иначе//Если проверка пройдена, т.е. комп доложился нормально
//Если извещение было
Если ЗначениеЗаполнено(ДатаПоследнегоИзвещения) Тогда
Если ТекущаяДата() - ДатаПоследнегоИзвещения < КоличествоМинутДляПовторногоИзвещения * 60 Тогда
Тема = "База 1с опять заработала после не пройденной проверки на компе: " + Строка.Ссылка + " Спустя " + Цел((ТекущаяДата() - ДатаПоследнегоИзвещения) / 60) + " минут после последнего извещения.";
Тело = Тема;
Если ЗначениеЗаполнено(ДатаПоследнегоИзвещения) Тогда
Тело = Тело + Символы.ПС + "Дата последней активности компа: " + ?(НЕ ЗначениеЗаполнено(ДатаПроверки), " не указана", ДатаПроверки);
Тело = Тело + Символы.ПС + "Дата последнего извещения: " + ДатаПоследнегоИзвещения;
КонецЕсли;
//Нужно отправлять письмо
ОтправлятьПисьмо = истина;
ИскСтрока.ДатаПоследнегоИзвещения = '00010101'; //Сбрасываем дату последнего извещения
КонецЕсли;
КонецЕсли;
КонецЕсли;
//Отправляем письмо
Если ОтправлятьПисьмо Тогда
Сообщить(Тема);
Сообщить(Тело);
Тело = Тело + Символы.ПС + "Отправлено в: " + ТекущаяДата();
ФРАНЧ.ОтправитьПисьмо(, Получатели, Тема, Тело);
КонецЕсли;
КонецЦикла;
//Сохраняем в файл список последних оповещений
Т = Новый ТекстовыйДокумент();
Т.УстановитьТекст(ЗначениеВСтрокуВнутр(СтруктураНастроек));
Т.Вывод = ИспользованиеВывода.Разрешить;
Т.Записать(ФайлСохраненияНастроек);
Сообщить(ФайлСохраненияНастроек);
Таким образом достаточно просто была решена поставленная заказчиком задача.