Вот, допустим, есть сеанс 77, робот 24/7
Нужны технологические окна, для проведения работ/обновления.
Допустим, кидаем файл-семафор - робот завершается (ну и прочие сеансы также)
Сделали что надо по техобслуживанию, файл-семафор убили.
Надо чтобы робот автоматом запустился.
Как это сделать? Ставим в планировщик виндовз задание (например, раз в 5 мин), которое делает типа так:
- проверяем наличие файл-семафор, если есть - ничего не делаем
- файл-семафора нет, удаляем в каталоге робота *.lck
- проверяем наличие в каталоге робота *.lck? если есть - ничего не делаем (робот уже работает), если нет - запускаем сеанс робота
.
типа так?
может еще какие варианты попроще/поизящнее есть?
А вот тот, кто семафор убивает в момент окончания тех.обслуживания, разве не может следом запустить робота?
Может, конечно, но все равно придется делать отдельный ярлык-задание на запуск, чтобы не болтался рядом в том же вин-сеансе пользователя
У меня реализовано так. Изначально делалось для контроля за работой программы. Т.е. если робот завис или упал из-за ошибки. Каждую минуту (у меня сейчас 3 минуты) робот обновляет сигнальный файл, в котором сохранен ИД процесса робота в Windows. Также каждую минуту планировщик запускает написанную на C# программу, которая проверяет время изменения сигнального файла. Если файл не менялся более 5 минут (настраивается), то если есть процесс, который записан в сигнальном файле, то он сбрасывается. После этого запускается процесс робота.
Всё вроде бы просто, но на некоторых серверах этот процесс как-то калечно начинает работать - каждую минуту запускает процесс робота до тех пор пока Windows говорит - всё, ресурсы для запуска закончены...
У механизма есть еще один недостаток - чтобы он работал, необходимо чтобы под пользователем Windows был выполнен вход в сеанс. Т.е. после перезагрузки или сеанс срубили из Диспетчера служб удаленных рабочих столов.
В роботе должен быть такой код:
Перем глСтатус;
Перем СледующееОбновлениеФайлаФлагаРаботы;
Перем ПериодОбновленияФайлаФлагаРаботыСС;
Перем ИмяФайлаФлагаРаботы;
Перем ИДТекущегоПроцесса1С;
//*****************************************************************************
// Функция возвращает PID процесса 1с
// Подсказал "Кириллка" с форума "Миста"
Функция глПолучитьPID() Экспорт
чPID = -1;
Попытка
oLocator = СоздатьОбъект("WbemScripting.SWbemLocator");
oService = oLocator.ConnectServer(".", "root\CIMV2");
// Запускаем дочерний rundll32.exe
oShell = СоздатьОбъект("WScript.Shell");
oApp = oShell.Exec("rundll32.exe kernel32,Sleep");
// Получаем rundll32 по PID'у
oChildProcess = oService.Get("Win32_Process.Handle=" + oApp.ProcessID);
// Получаем PID родительского процесса - 1с
чPID = oChildProcess.ParentProcessID;
// Завершаем rundll32, чтобы не мусорить
oChildProcess.Terminate();
Исключение
// нуу, может не быть прав на эти вещи, например.
КонецПопытки;
Возврат чPID;
КонецФункции //глПолучитьPID
//*****************************************************************************
Процедура ПриИзмененииФлагаРаботыПрограммы()
Если флОбновлятьФлагРаботыПрограммы = 1 Тогда
СледующееОбновлениеФайлаФлагаРаботы = глСтрТекДатаВремя();
ПериодОбновленияФайлаФлагаРаботыСС = 180;
ИмяФайлаФлагаРаботы = КаталогВременныхФайлов() + ИмяПользователя() + ".flg";
ИДТекущегоПроцесса1С = Строка(глПолучитьPID());
КонецЕсли;
КонецПроцедуры //ПриИзмененииФлагаРаботыПрограммы
//*****************************************************************************
Процедура РабочийПроцесс()
Если глСтатус = 0 Тогда
Возврат;
КонецЕсли;
ФормаРасш.ОбработкаОжидания("РабочийПроцесс", ИнтервалОтправкиСМС * 1000);
глСервис.ВнешнееСобытие("Форма", "РабочийПроцесс", "");
глСтатус = 1; //в ожидании
КонецПроцедуры //РабочийПроцесс
//*****************************************************************************
Процедура ЗапускСлужбы(ЗапуститьЧерез=100)
глСтатус = 1;
Форма.ттСтатус.Заголовок("Процесс запущен...");
ФормаРасш = СоздатьОбъект("РасширениеФормы");
ФормаРасш.ОбработкаОжидания("РабочийПроцесс", ЗапуститьЧерез);
КонецПроцедуры //ЗапускСлужбы
//*****************************************************************************
Процедура ОстановитьСлужбу()
Если глСтатус > 0 Тогда
глСтатус = 0;
ФормаРасш.ОбработкаОжидания("РабочийПроцесс", 0);
Форма.ттСтатус.Заголовок("Процесс остановлен...");
КонецЕсли;
КонецПроцедуры //ОстановитьСлужбу
//*****************************************************************************
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
Если (Источник <> "Форма") ИЛИ (Событие <> "РабочийПроцесс") Тогда
глВывестиМногострочноеСообщение("Источник = " + Источник + " Событие = " + Событие + " Данные = " + Данные);
Возврат;
КонецЕсли;
СохрСтатус = глСтатус;
глСтатус = 0;
Если флОбновлятьФлагРаботыПрограммы = 1 Тогда
СтрДатаВремяТекущийМомент = глСтрТекДатаВремя();
Если СледующееОбновлениеФайлаФлагаРаботы <= СтрДатаВремяТекущийМомент Тогда
ТекстФайлаФлага = СоздатьОбъект("Текст");
ТекстФайлаФлага.ДобавитьСтроку(ИДТекущегоПроцесса1С);
ТекстФайлаФлага.Записать(ИмяФайлаФлагаРаботы);
СледующееОбновлениеФайлаФлагаРаботы = глДобавитьКСтрДатаВремя(СтрДатаВремяТекущийМомент, 0, 0, 0, ПериодОбновленияФайлаФлагаРаботыСС);
КонецЕсли;
КонецЕсли;
//Здесь выполняем нужные нам действия
глСтатус = СохрСтатус;
КонецПроцедуры //ОбработкаВнешнегоСобытия
//*****************************************************************************
Процедура ПриОткрытии() //предопределенная
глСтатус = 0;
флОбновлятьФлагРаботыПрограммы = ВосстановитьЗначение("РегламентныеЗадачи_флОбновлятьФлагРаботыПрограммы");
ПриИзмененииФлагаРаботыПрограммы();
Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
Если Форма.Параметр.Получить("Команда") = "Запустить" Тогда
оЗапускПоТаймеру = СоздатьОбъект("Общие.ЗапускПоТаймеру");
оЗапускПоТаймеру.Инит(Контекст,
"Процедура _ЗапускСлужбы()
| ЗапускСлужбы();
|КонецПроцедуры",
"_ЗапускСлужбы");
оЗапускПоТаймеру.Запустить(1000);
КонецЕсли;
КонецЕсли;
КонецПроцедуры //ПриОткрытии
Некоторые выполняемые действия могут вызывать зависания 1С, если они запущены из процедуры РабочийПроцесс, поэтому пришлось сделать ход конем и перенести их в процедуру ОбработкаВнешнегоСобытия, которую вызываю через механизм внешних событий FormEx.
Настройки контролирующей программы находятся в set.ini
Там есть строка с disable=0. Она означает, что необходимо контролировать. Если выставить в параметр в 1, то программа не будет осуществлять контроль. Это удобно, когда нужно сделать сервисные действия (обновить конфу, например)
Архив с программой: https://disk.yandex.ru/d/8jXYXRN7WvEISQ
Спасибо, подумаю...