Cервер &CronSrv
Назначение и краткое описание
Какая польза от &CronSrv?
"Защитник" CronGuard, или "Ванька-Встанька"
|
Пример CRON скрипта
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\CronServer\CronSrv.cfg
[&CronSrv.StartupScript]
@cron.tab DailyMorning 0 8
@cron.job DailyMorning @Speak Good morning, it's 8:00.
@cron.tab DailyEvening 45-60/5 16 * * Mon-Thu
@cron.job DailyEvening @run -hide msg.exe * /time:5 "Go home. Have a nice evening."
@cron.tab EveryWeekend 45-60/3 15 * * Fri
@cron.job EveryWeekend @run -hide msg.exe * /time:5 "Go home. Have a nice weekend."
@Cron.tab DimDns *
@Cron.job DimDns @IfNotProcessExists dns.exe @Speak Run DNS.EXE, if one not running.
@Cron.job DimDns @IfNotProcessExists dns.exe @Run -hide CronDimDns.bat -d
@Cron.tab Defrag 0 12 * * Fri
@Cron.job Defrag @IfNotProcessExists defrag.exe @Speak Defragment disks every Friday 12:00.
@Cron.job Defrag @IfNotProcessExists defrag.exe @Run -hide CronDefrag.bat
[]
|
К началу
Назначение и краткое описание
Сервер &CronSrv предназначен для выполнения заданий "по расписанию"
в составе измерительных систем пакета CRW-DAQ.
Название Cron взято от греческого Кронос -
Κρόνος
- бог Времени из древнегреческих мифов.
Довольно частой проблемой в практике автоматизации измерительных систем является необходимость
выполнения тех или иных заданий (последовательности действий) по расписанию, например,
периодических или по календарным событиям.
Например, в ряде случаев требуется периодически (допустим, раз в неделю) запускать
дефрагментацию дисков или резервное копирование файлов.
Эта задача особенно актуальна для систем длительного круглосуточного действия,
которые должны сами, без участия оператора, полностью обслуживать систему, например,
архивировать файлы данных, чистить диски от старых файлов и так далее.
Для решения подобных задач можно, разумеется, использовать тот или иной планировщик
(штатный Windows Scheduler, программу nnCron и т.д.).
Однако это получается крайне неудобно, так как, во-первых, эти планировщики слабо связаны с основным
измерительным пакетом и не синхронизованы с ним, а во-вторых, описание конфигурации "расползается"
по разным местам, часто трудно доступным, вместо того, чтобы сосредоточиться в одном каталоге измерительной системы.
Кроме того, задания &CronSrv исполняются с правами пользователя, под которым запущена и измерительная
система (обычно этот пользователь имеет права администратора), поэтому не возникнет проблем с правами и учетными
записями пользователя.
Сервер Cron позволит упорядочить и унифицировать описание таких задач и облегчить их сопровождение.
Он позволяет описывать в едином формате момент наступления
как периодических, так и уникальных (календарных) событий, а также организовывать
запуск обработчиков событий, или, по принятой терминологии, заданий.
Эти задания можно использовать также и для обработки асинхронных событий, которые вызываются из
других программ как готовые подпрограммы с помощью механизма сообщений (DevMsg, DevSend, DevPost, DevSendMsg, DevPostMsg).
Кроме того, сервер содержит большое число готовых к исполнению команд,
которые можно вызывать как готовые подпрограммы для асинхронного вызова из других программ,
также с помощью механизма сообщений.
Например, вызов браузера для просмотра справочного файла можно выполнить так:
if DevPostMsg('&CronSrv @Browse ..\Help\index.htm'+EOL)=0 then writeln('Не могу запустить Help!');
Сервер &CronSrv может работать в двух режимах - в календарном
(время привязано к календарю) и в импульсном (генерируются периодические события). Эти режимы
в совокупности закрывают огромное число задач, связанных с временем, планированием работы установки и
организацией тех или иных циклов ее работы.
При использовании сервера &CronSrv не надо забывать, что он имеет ряд ограничений.
В текущей версии размер задания - не более 16 kByte, а число заданий - не более 1024.
Кроме того, сервер отслеживает наступление событий, только пока работает DAQ-система,
поэтому при временных остановках DAQ-системы события, которые наступили во время ее
остановки и простоя, будут пропущены (что, в общем-то, естественно). Предполагается, что основным
"потребителем" функций сервера &CronSrv станут длительно работающие системы
и установки, для которых характерен непрерывный режим работы в течение длительного времени,
где эта проблема не стоит.
Другим "потребителем" функций сервера станут стартовые задания, помещаемые в секцию
[&CronSrv.StartupScript]. Например, все функции стартовой настройки окон
GUI можно будет помещать в эту секцию. Большое число команд
сервера позволит унифицировать стартовые скрипты, сведя наибольшую часть стартовых
действий в одну секцию [&CronSrv.StartupScript]. Это позволит также
за счет унификации сократить объем кода прикладных систем, которые смогут использовать
стандартный набор команд для часто востребуемых действий.
Наличие завершающей секции [&CronSrv.FinallyScript] позволяет выполнять
некоторые действия по завершению работы системы. Например, можно при завершении работы DAQ-системы
также завершить работу каких-то внешних процессов или запустить резервное копирование данных.
К началу
Польза от использования &CronSrv
Использование &CronSrv может принести пользу в следующих случаях:
- &CronSrv позволяет унифицировать (стандартизовать) все задачи, связанные со временем и календарем.
- &CronSrv позволяет работать в двух режимах
- режиме календарных событий (CronTab) и в режиме генерации периодических событий - импульсов (Pulse).
- &CronSrv позволяет отделить календарь (планировщик) от исполнительной части.
Например, прикладная программа может создать обработчик некоторого сообщения,
и затем создать задание для &CronSrv, которое посылает нужное сообщение в нужное время.
- &CronSrv позволяет создавать "умные" системы, которые сами себя обслуживают: дефрагментируют
и чистят диски, делают резервные копии данных, завершают работу в заранее заданное время, напоминают
оператору о наступлении заданных моментов времени и т.д. Набор полезных стандартных утилит
позволяет облегчить решение обычно стоящих задач - дефрагментация, резервное копирование данных,
очистка дисков от устаревших файлов данных, сжатие и архивирование данных.
- &CronSrv позволяет контролировать запланированные задания, а также задавать "на лету"
новые задания (через сообщения и через консоль &CronSrv). Это повышает гибкость работы установок
и позволяет оперативно (без программирования и без остановки измерений) планировать работу установок.
Например, если стало известно, что в 03:00 ночи отключат электричество, то на 02:45 можно
запланировать автоматическое завершение работы системы - не прерывая работы установки.
- Задания &CronSrv позволяют группировать некоторые последовательности
действий и затем вызывать их как асинхронно (путем посылки сообщений), так и по
расписанию. Фактически задания &CronSrv - это готовые к исполнению
подпрограммы, которые можно конструировать "на лету", не прерывая измерений.
- Наличие стартовой секции [&CronSrv.StartupScript] и завершающей
секции [&CronSrv.FinallyScript] позволяет сосредоточить основные
стартовые и завершающие действия в одном месте. Большое количество готовых команд позволяет
создавать (без программирования на уровне Daq Pascal) довольно содержательные стартовые
и завершающие скрипты, например, задающие размеры и внешний вид окон GUI, вызывающие
или завершающие те или иные внешние программы, посылающие при старте сообщения другим устройствам и т.д.
Прикладные программы могут теперь не создавать своих стартовых секций, а помещать
свои стартовые команды в секцию [&CronSrv.StartupScript].
Все нужные стартовые действия в других устройствах могут быть выполнены путем посылки
сообщений (@DevMsg, @DevSend, @DevPost, @DevSendMsg, @DevPostMsg) из стартовой секции [&CronSrv.StartupScript].
- &CronSrv позволяет сократить объем прикладного программирования, так как
позволяют использовать большой набор готовых команд &CronSrv, не создавая
собственных аналогов в каждой из новых систем.
Теперь стоит сказать о том, чего &CronSrv не может:
- &CronSrv не предназначен для организации быстрых и частых событий.
В календарном режиме CronTab оперирует временами от минуты и более.
В режиме Pulser время задается в миллисекундах, но возможны задержки
порядка 20-30 ms за счет использования очереди и сообщений.
- &CronSrv не предназначен для организации событий с очень точной
привязкой по времени. Точность привязки событий по времени составляет
порядка 20-30 ms.
К началу
Состав и конфигурирование &CronSrv
Сервер &CronSrv расположен в каталоге Resource\DaqSite\CronServer\,
и включает файлы:
- cronsrv.htm - файл справки.
- cronsrv.pas - файл с программным кодом на языке DaqPascal.
- cronsrv.cfg - файл с типичной конфигурацией, для включения в [ConfigFileList].
Для включения сервера &CronSrv в конфигуращию надо его объявить и сконфигурировать.
В большинстве случаев подойдет стандартный конфигурационный файл, для включения которого
будет достаточно написать:
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\CronServer\CronSrv.cfg
[]
Если стандартный конфигурационный файл почему-то не подходит,
можно переопределить отдельные параметры в секции [&CronSrv]
в основном конфигурационнм файле, например:
[&CronSrv]
DevicePolling = 10, tpTimeCritical
StdInFifo = 1024
StdOutFifo = 1024
Можно также отказаться от стандартного конфигурационного файла, а вместо него
включить и отредактировать такой фрагмент:
[DeviceList]
&CronSrv = device software program
[&CronSrv]
Comment = CRON server to launch jobs at specified time
InquiryPeriod = 1
DevicePolling = 10, tpHighest
ProgramGuard = ~~\Resource\DaqSite\CronServer\CronGrd.exe
ProgramSource = ~~\Resource\DaqSite\CronServer\CronSrv.pas
StartupScript = [&CronSrv.StartupScript]
FinallyScript = [&CronSrv.FinallyScript]
StopTimeOut = 5000
StdInFifo = 512
StdOutFifo = 512
OpenConsole = 2
DebugFlags = 3
SilentEval = 0
StartingOrder = -4096
StoppingOrder = +4096
[]
Сервер &CronSrv, кроме своей основной секции [&CronSrv], имеет также
две другие стандартные секции: стартовую секцию [&CronSrv.StartupSection]
и завершающую секцию [&CronSrv.FinallySection].
Стартовая секция [&CronSrv.StartupSection] выполняется при старте сервера и
помещает приведенные в ней команды в консоль ввода StdIn устройства &CronSrv
для дальнейшей обработки в стандартном цикле опроса.
Исполнение команд происходит абсолютно так же, как если бы все эти команды были введены вручную в консольном окне
или посланы через сообщения. Стартовая секция, за счет большого числа доступных команд,
дает возможность стандартным образом выполнять инициализирующие действия, например, задавать при старте системы
параметры окон или запускать те или иные внешние программы.
Завершающая секция [&CronSrv.FinallySection] выполняется при остановке сервера и
помещает приведенные в ней команды в консоль ввода StdIn устройства &CronSrv,
чтобы немедленно после этого их исполнить. Исполнение этой секции имеет ряд особенностей.
Во-первых, поскольку обычно завершающая секция исполняется при завершении работы DAQ-системы,
то не следует рассчитывать на то, что посланные в секции сообщения будут получены другими устройствами
и исполнены, так как эти устройства могут быть уже остановлены к моменту исполнения секции завершения.
По этой причине посылать сообщения не рекомендуется - это не будет надежно работать.
Отсроченные команды, основанные на посылке сообщений "самому себе", в завершающей секции также могут быть
проигнорированы, по той же причине.
Тем не менее, достаточно большое число непосредственно исполняемых команд, например,
команды @winshow, @winhide, @windraw, @winselect, @showmaintoolbar, @showmainstatusbar, @showmaindaqcontrol,
@eval, @run, @ifprocessexists, @iffileexists, @ifdirexists, ifcomputername, @fileopendialog
и другие по-прежнему доступны для исполнения.
Другой особенностью является то, что на исполнение завершающих команд отводится ограниченное время, заданное
параметром StopTimeOut, в миллисекундах. Если этот параметр равен нулю, исполнение завершающей секции
вообще отменяется. Команды, которые сервер не успел выполнить за отведенное время, игнорируются.
После этого следует описать задания, которые будет выполнять сервер &CronSrv.
Стандартный путь описания заданий - помещение в стартовую секцию [&CronSrv.StartupScript] сервера
соответствующего набора команд, наиболее важные среди которых - создание задания
@cron.tab и добавление команды к заданию @cron.job.
Команда @cron.tab определяет имя задания и время его наступления по расписанию.
Команда @cron.pul позволяет включить режим периодических событий (Pulser).
Команды @cron.job добавляют к созданному заданию исполняемые команды.
Команда @cron.run позволяет запускать созданное задание досрочно, например,
для тестирования или для обработки асинхронных событий, генерируемых с помощью сообщений.
Команда @cron.del позволяет удалять задания из списка заданий.
Команда @cron.enb позволяет запретить или разрешить задание,
если по каким-то причинам исполнение задания по расписанию должно быть временно приостановлено.
Например (см также тут):
[&CronSrv.StartupScript]
;--- Каждое утро в 8:00 ударять в гонг и говорить приветствие
@Cron.tab DailyMorning 0 8
@Cron.job DaylyMorning @Voice Gong
@Cron.job DailyMorning @Speak Доброе утро, сейчас 8:00.
;--- Каждую пятницу в 16:00 ударять в гонг и желать приятного отдыха
@Cron.tab EveryWeekend 0 16 * * Fri
@Cron.job EveryWeekend @Voice Gong
@Cron.job EveryWeekend @Speak Рабочая неделя кончилась! Приятного отдыха!
;--- Каждую секунду посылать сообщение @Update устройству &GUI
@Cron.tab EverySecond 0 0 0
@Cron.pul EverySecond 1000
@Cron.job EverySecond @DevPostMsg &GUI @Update
[]
Cекция [&CronSrv.StartupScript] является стандартным, но не единственным способом
создания заданий. Задания могут генерироваться командами, поступающими
от других программ с помощью сообщений. Например:
if DevSend(RefFind('Device &CronSrv'),
'@Cron.tab EveryEvening 0 17'+EOL+
'@Cron.job EveryEvening @Speak Добрый вечер, сейчас 17:00.'+EOL)>0
then writeln('Ok') else writeln('Could not send!');
Наконец, задания могут создаваться и запускаться в консоли [&CronSrv] вручную.
Это обстоятельства позволяет "на ходу" смотреть и менять план работы системы, создавать и запускать
задания в любое время, тестировать или запускать досрочно запланированные задания.
Хотя это и не совсем тривиальные действия, но они дают возможность планировать работу системы,
не прерывая измерений, что является довольно ценным качеством.
К началу
Задания &CronSrv
Центральным понятием &CronSrv является задание.
Задание (англ. job) является поименованной (имеющей уникальное имя)
последовательностью действий, в конкретном случае &CronSrv - последовательностью
команд. Задание также имеет расписание - описание моментов времени,
когда оно должно исполняться, а также флаг разрешения и запрещения.
В настоящей версии &CronSrv текст задания не должен превышать 16 kByte,
а число заданий - не более 1024.
Каждое задание может работать в двух режимах -
календарном (время в расписании задается в терминах календаря) и
импульсном (задается период повторения событий и счетчик).
Каждый из режимов удобен для своего круга задач.
Задания создаются командой @cron.tab, которая определяет имя задания
(оно должно быть уникальным в рамках данной конфигурации) и время его наступления по календарному
расписанию в Cron-формате. С помощью команды @cron.pul
задание может использоваться в импульсном режиме (Pulser), когда генерируются периодические
события с заданным периодом, начиная с текущего момента.
С помощью команды @cron.job к созданному заданию добавляют исполняемые команды.
Исполнение задания состоит в том, что заданные команды помещаются в консоль ввода StdIn
сервера &CronSrv и начинают последовательно исполняться. Исполнение задания может
инициироваться как по расписанию (если задание разрешено), так и по команде
@cron.run, которая позволяет запускать созданное задание досрочно.
Это нужно, например, для тестирования задания или для обработки асинхронных событий,
генерируемых с помощью сообщений. Если задание больше не нужно,
команда @cron.del позволяет удалять задания из списка заданий.
Команда @cron.enb позволяет запретить или разрешить задание,
если по каким-то причинам исполнение задания по расписанию должно быть временно приостановлено.
Наконец, текущий список заданий можно посмотреть командой @cron.see.
Задания могут описываться как статически (при загрузке системы,
в секции [&CronSrv.StartupScript]), так и динамически, по командам от других
программ, которые могут использовать сервер &CronSrv для организации периодических
или календарных событий в своих целях, добавляя задания по мере необходимости.
К началу
Два режима работы заданий &CronSrv
Задания сервера &CronSrv могут работать в двух режимах:
- Календартный или CronTab - время наступления заданий задается в терминах календарного
времени (заданного в Cron-формате) с помощью команды @cron.tab
и "привязано" к календарю.
Это режим удобен для организации "человеческих" событий, происходящих сравнительно редко
и обычно связанных с календарем, например, конец рабочего дня, полдень и т.д.
Например:
@cron.tab DailyMorning 0 8 - Создать календарное задание "каждый день в 8:00"
@cron.job DailyMorning @Speak Доброе утро! - При выполнении говорить: Доброе Утро!
- Импульсный или Pulser - время наступления заданий определяется в терминах линейного
времени с помощью команды @cron.pul. Эта команда задает, начиная с текущего момента,
период импульсов (заданный в миллисекундах) и счетчик (число событий, которые надо сгенерировать).
Этот режим удобен для организации "машинных" событий, происходящих периодически и обычно связанных
с линейным временем.
Например:
@cron.tab EverySecond 0 0 0 - Создать задание, но не календарное
@cron.pul EverySecond 1000 - Стартовать Pulser с периодом 1000 ms, без счетчика
@cron.job EverySecond @DevPostMsg &GUI @Update - При выполнении посылать команду @Update устройству &GUI
@cron.tab Three_Times 0 0 0 - Создать задание, но не календарное
@cron.pul Three_Times 10000 3 - Стартовать Pulser с периодом 10000 ms, выполнять только 3 раза
@cron.job Three_Times @DevPostMsg &GUI @Refresh - При выполнении посылать команду @Refresh устройству &GUI
Следует заметить, что два указанных режима не являются альтернативными и могут использоваться совместно, если это
требуется для решения задачи. Для этого достаточно применить обе команды (@cron.tab,
@cron.pul) - и исполнение заданий будет инициироваться обоими условиями.
К началу
Команды &CronSrv
Сервер &CronSrv имеет (кроме стандартного набора) следующий набор команд:
- @Cron.tab job tab - создать новое задание по имени job,
которое будет выполняться по расписанию tab, заданном в Cron-формате.
Имя задания используется для его дальнейшей идентификации и должно быть уникальным в рамках проекта.
Вновь созданное задание - пустое, то есть оно пока не содержит команд для исполнения.
Предполагается, что содержимое задания будет задано позже вызовом команды @cron.job.
Если задание с указанным именем существовало, оно будет удалено и на его месте будет создано новое,
пустое задание. В некоторых случаях имеет смысл создавать задания, которые никогда не выполняются
по расписанию - например, это могут быть обработчики асинхронных событий от других устройств.
Для создания таких заданий достаточно указать в Cron-формате несуществующее время - наример,
нулевой день месяца.
Пример:
@cron.tab DailyMorning 0 8 Задание DailyMorning для исполнения в 8:00 каждое утро
@cron.tab EveryWeekend 0 16 * * Fri Задание EveryWeekend для исполнения в 16:00 каждую пятницу
@cron.tab EventHandler 0 0 0 Задание не будет выполняться по расписанию - задан 0 день месяца
- @Cron.pul job per cnt - стартовать для задания по имени job
генератор импульсов (Pulser), с периодом импульсов per миллисекунд,
и счетчиком событий cnt, задающим максимальное число событий.
Если счетчик cnt не задан, то число событий не ограничено.
Если период per не задан или равен нулю, или если счетчик cnt равен нулю,
то Pulser отключается и перестает генерировать события.
Задание job должно быть создано ранее командой @cron.tab.
Чтобы отключить генерацию "календарных" событий при создании задания, работающего
в импульсном режиме, достаточно указать время, которое
никогда не наступит, например,
@cron.tab Never 0 0 0 - никогда не наступит, потому что день месяца не может быть нулем
Пример:
@cron.tab EverySecond 0 0 0 - Создать задание, но не календарное
@cron.pul EverySecond 1000 - Стартовать Pulser с периодом 1000 ms, без счетчика
@cron.tab Three_Times 0 0 0 - Создать задание, но не календарное
@cron.pul Three_Times 10000 3 - Стартовать Pulser с периодом 10000 ms, выполнять только 3 раза
- @Cron.job job cmd - добавить команду cmd к заданию по имени job.
Задание job должно быть создано ранее командой @cron.tab.
При наступлении момента времени, заданного в команде @cron.tab job ..., сервер помещает все команды
cmd, указанные при описании задания, в консоль ввода StdIn устройства &CronSrv
для дальнейшего исполнения.
Пример:
@cron.job DailyMorning @Speak Доброе утро!
@cron.job EveryWeekend @Run -hide msg.exe * /time:15 "Пора домой! Приятных выходных!"
- @Cron.del job - удалить задание по имени job из списка заданий.
Пример:
@cron.del DailyMorning
- @Cron.enb job enb - разрешить (enb=1) или запретить (enb=0)
исполнение задания по имени job по расписанию.
Пример:
@cron.enb DailyMorning 1 Разрешить задание DailyMorning
@cron.enb EveryWeekend 0 Запретить задание EveryWeekend
- @Cron.run job - запустить на исполнение задание по имени job.
Это полезно, если по каким-то причинам потребовалось досрочно исполнить задание,
которое обычно исполняется по расписанию. Можно также задавать задания, которые
запрещены к исполнению по расписанию, и запускать их по каким-то внешним условиям,
как готовую подпрограмму.
Пример:
@cron.run EventHandler Запустить на исполнение задание EventHandler
- @Cron.see job - посмотреть содержимое задания по имени job.
Если имя задания не указано, посмотреть полный список всех заданий, в сокращенном виде.
Если имя задания - * (звездочка), то посмотреть полный список всех заданий, в подробном виде.
Пример:
@cron.see DailyMorning Посмотреть содержимое задания DailyMorning
@cron.see * Посмотреть все задания, подробно
@cron.see Посмотреть все задания, кратко
- @Cron.cpu s - команда отчета о статистике использования процессора (CPU).
При значении s=start сбрасывает все счетчики и начинает сбор статистики "с нуля".
Если s не указано, распечатывает отчет об использовании процессора устройством &CronSrv.
Команда поможет выяснить, не слишком ли сильно сервер &CronSrv загружает процессор.
Пример:
@cron.cpu start Начать набор статистики с начала
@cron.cpu Распечатать отчет о загрузке CPU
Типичный отчет содержит строки:
Average - средняя загрузка за время наблюдения
LastSec - средняя загрузка в последнюю секунду
Peaking - пиковое значение загрузки за секунду
В столбцах содержатся значения таких параметров:
Kernel,% - загрузка потока, в режиме ядра, %
User,% - загрузка потока, в режиме пользователя, %
Thread,% - загрузка потока, суммарная в обоих режимах, %
VDPM,kOp/sec - загрузка виртуальной машины Daq Pascal, тысяч операций в секунду
Например:
&CRONSRV : Profiler report at 2011.04.05-17:34:04: 979 sec.work
&CRONSRV : ---------+----------+----------+----------+-------------
&CRONSRV : CPU Load | Kernel,% | User,% | Thread,% | VDPM,kOp/sec
&CRONSRV : ---------+----------+----------+----------+-------------
&CRONSRV : Average | 0.027 | 0.021 | 0.048 | 62.917
&CRONSRV : LastSec | 0.000 | 0.000 | 0.000 | 62.454
&CRONSRV : Peaking | 3.031 | 1.539 | 3.076 | 140.397
&CRONSRV : ---------+----------+----------+----------+-------------
Как видно из примера (использовалась конфигурация DEMO_CRON), средняя загрузка
процессора в данном случае ничтожна (менее 0.05%), а пиковая - не превышает 3%.
Насколько этот случай можно считать типичным - покажет практика.
- @WinHide w - Спрятать окно по имени w.
- @WinShow w - Показать окно по имени w.
- @WinDraw w|o - Перерисовать окно по имени w с опциями рисования o.
- @WinSelect w - Показать окно по имени w и выделить его (сделать активным).
Пример:
@winhide DAQ-СИСТЕМА Спрятать окно DAQ-СИСТЕМА
@winshow ГЛАВНАЯ КОНСОЛЬ Показать окно ГЛАВНАЯ КОНСОЛЬ
@windraw ГЛАВНАЯ КОНСОЛЬ|top=0|Left=167 Перерисовать окно ГЛАВНАЯ КОНСОЛЬ в новом положении
@winselect ГЛАВНАЯ КОНСОЛЬ Выделить (сделать активным) окно ГЛАВНАЯ КОНСОЛЬ
- @ShowMainToolBar n - Спрятать/показать (n=0/1) главную панель команд (ToolBar).
- @ShowMainStatusBar n - Спрятать/показать (n=0/1) главную статусную строку (StatusBar).
- @ShowMainDaqControl n - Спрятать/показать (n=0/1) окно главной панели управления DAQ (окно DAQ-СИСТЕМА).
Пример:
@ShowMainToolBar 0 Спрятать ToolBar
@ShowMainStatusBar 1 Показать StatusBar
@ShowMainDaqControl 0 Спрятать окно DAQ-СИСТЕМА
- @Async cmd - Асинхнонное (отложенное) исполнение команды cmd.
Команда cmd посылается в консольный буфер StdIn устройства &CronSrv
для дальнейшего исполнения. Так, асинхронное исполнение позволяет организовать однократно
исполняемые задания, которые после завершения сами удаляют себя из списка заданий
с помощью отложенной команды удаления. Удалять себя из списка во время исполения
было бы некорректным решением.
Пример:
@Cron.tab RunOnce * Создать ежеминутное задание RunOnce
@Cron.job RunOnce @Speak Hello, world! Добавить команды для исполнения этого задания
@Async @Cron.del RunOnce Отложенная команда - удалить задание RunOnce
- @Eval expr - вызвать функцию Eval для интерпретации выражения expr.
Смотрите документацию Daq Pascal по функции Eval для выяснения подробностей.
Пример:
@Eval @System @Async @Run -hide msg.exe * /time:15 "Пример вызова окна сообщения в течение 15 секунд."
@Eval @System @Async @View Hide Crw32.ToolBar - Спрятать панель команд ToolBar
- @SilentEval n - вызвать задать "тихий" режим n вычислений.
В "тихом" режиме по возможности подавляются сообщения в окне Главная Консоль при интерпретации выражений.
"Тихий" режим влияет на исполнение команд: @Run, @Pid, @Shutdown,
@FileOpenDialog, @ShowMainToolbar, @ShowMainStatusBar, @ShowMainDaqControl.
Пример:
@SilentEval 1 Включить "тихий" режим
@Run cmd Запустить cmd
@ShowMainToolBar 0 Спрятать ToolBar
@ShowMainStatusBar 1 Показать StatusBar
@ShowMainDaqControl 0 Спрятать окно DAQ-СИСТЕМА
- @Run /opt cmd - выполнить (с необязательными опциями opt) команду операционной системы cmd.
Эта команда эквивалентна вызову @Eval @System @Async @Run /opt cmd.
Полный список опций /opt можно узнать, набрав в окне ГЛАВНАЯ КОНСОЛЬ команду @Run без аргументов.
Пример:
@Run -hide -lower -cd Temp cmd /c msg.exe * /time:15 "Пример вызова окна сообщения в течение 15 секунд."
Расшифровка:
-hide - исполнение команды в скрытом окне, которого не видно на экране
-lower - запуск с низким приоритетом (/Idle/Lower/Normal/High/RealTime)
-cd Temp - задать стартовый каталог Crw32exe\Temp (по умолчанию - Crw32exe)
cmd /c - стандартный вызов командного интерпретатора cmd.exe
приведено для примера - в данном случае можно обойтись без него
msg.exe * - команда вызова диалогового окна для всех пользователей (*)
/time:15 - указание автоматически закрыть диалоговое окно через 15 секунд
"Пример .." - Текст сообщения, который будет показан в окне
Данный пример полезен для организации автоматических напоминаний и уведомлений пользователя
о наступлении тех или иных событий.
Следует заметить, что команда @run обычно (по умолчанию) запускает программу в каталоге
~~\, то есть Crw32exe. Если требуется изменить каталог запуска, это делается с
помощью опции @run -cd dir ..... Таким образом удобно ссылаться на подкаталоги домашнего
каталога Crw32exe. Например, @run -cd Temp .... запустит программу в каталоге
Crw32exe\Temp. К сожалению, со ссылками на каталог DAQ-системы дело обстоит
несколько сложнее - ее сложно прямо указать в опции @run -cd ...., приходится делать иначе.
Если запускаемой программе требуется узнать имя конфигурационного файла или каталог данных текущей
запущенной DAQ системы, то их надо узнать через переменные окружения:
- CRW_DAQ_CONFIG_FILE - имя основного конфигурационного файла текущей запущенной DAQ-системы.
- CRW_DAQ_CONFIG_HOME_DIR - домашний каталог основного конфигурационного файла текущей запущенной DAQ-системы.
- CRW_DAQ_CONFIG_DATA_PATH - каталог данных текущей запущенной DAQ-системы.
Это позволяет запускать программы в каталоге DAQ-системы:
Запустить cmd, перейти в каталог данных DAQ и запустить команду dir:
@Run cmd /с cd %CRW_DAQ_CONFIG_DATA_PATH% && dir
Запустить cmd в каталоге Crw32exe\Temp, и командный файл Demo.bat из каталога ..\Utility:
@Run -hide -cd Temp cmd /c %CRW_DAQ_CONFIG_DATA_PATH%\..\Utility\Demo.bat
При создании заданий следует учитывать, что команда @Run исполняется асинхронно, она НЕ ОЖИДАЕТ
завершения запускаемого процесса. По этой причине две последовательные команды @Run на самом деле
запустят два параллельных процесса, практически одновременно. Если по логике задачи некоторые действия
должны делаться последовательно, то рекомендуется вынести их в отдельный командный *.bat файл.
Этот файл, например, можно поместить в каталоге ..\Utility, не забыв добавить его в путь поиска
[DAQ] SearchPath = ... Это позволит обращаться к файлу в команде @Run по "короткому" имени,
не указывая путь.
Для того, чтобы исполнять типичные задания по обслуживанию системы, к серверу &CronSrv
прилагается ряд полезных утилит для дефрагментации дисков, чистки каталогов
данных, резервного копирования и т.д. Это ряд командных *.bat файлов, позволяющих упростить
вызов стандартных программ (defrag.exe, purger.exe, xcopy и других).
Эти утилиты также обеспечивают ведение журналов в *.log файлах, что полезно для анализа работы системы.
- @Pid op p e c - выполнить (с необязательными опциями op p e c) команду для работы с процессами.
Эта команда эквивалентна вызову @Eval @System @Async @Pid op p e c.
Полный список опций команды можно узнать, набрав в окне ГЛАВНАЯ КОНСОЛЬ команду @Pid без аргументов.
Здесь op - операция с процессами, например, list - список, kill - завершение процессов.
Параметр p задает номер процесса или его имя, e - код завершения, c - задает флаг завершения
потомков данного процесса. Например:
@pid kill dns.exe Завершить все процессы с именем dns.exe
@pid list Вывести в главную консоль список процессов
- @Browse url - открыть окно браузера для обозрения сайта url.
Пример:
@Browse http://cern.ch - Открыть сайт cern.ch
- @Speak text - сказать фразу, заданную в text.
- @Voice sound - проиграть звук, заданный в sound.
Эти команды позволяют организовывать звуковые эффекты.
Команда @speak выдает речевое сообщение text путем посылки сообщения
серверу &SpeakSrv - который, разумеется, должен быть описан в конфигурации.
Команда @voice позволяет проиграть звук, заданный в sound.
Этот звук является именем wav файла, который должен присутствовать либо в стандартной
библиотеке звуков, либо в каталоге, заданном [DAQ] SoundLibrary.
Пример:
@Speak Hello, world!
@Voice Siren
- @Error message - окно-сообщение об ошибке message.
- @Warning message - окно-сообщение с предупреждением message.
- @Information message - окно-сообщение с информацией message.
Эти команды позволяют выдавать окна с сообщениями и отличаются внешним оформлением
(сообщение об ошибке, предупреждение, информационное уведомление).
Текст сообщения message задан в URL-кодировке и может содержать
специальные символы, включаемые с помощью кода %xx.
Например, для перевода строки можно использовать %0D%0A, то есть CR LF.
Пример:
@Error Error message! %0D%0A %0D%0A Message 1. %0D%0A Message 2.
@Warning Warning message! %0D%0A %0D%0A Message 1. %0D%0A Message 2.
@Information Information message! %0D%0A %0D%0A Message 1. %0D%0A Message 2.
- @Shutdown Daq Exit sound - Завершить работу DAQ-системы со звуком sound.
- @Shutdown Daq Restart sound delay start - Перезагрузить DAQ-систему со звуком sound,
выполнить задержку delay секунд, и затем, если указан start=1, сделать её принудительный старт.
- @Shutdown Crw Exit sound - Завершить работу программы CRW со звуком sound.
- @Shutdown Win Exit sound delay - Завершить программу CRW со звуком sound,
затем, после задержки delay секунд, завершить работу Windows.
- @Shutdown Win Logout sound delay - Завершить программу CRW со звуком sound,
затем, после задержки delay секунд, завершить сеанс пользователя Windows.
- @Shutdown Win Restart sound delay - Завершить программу CRW со звуком sound,
затем, после задержки delay секунд, перезагрузить Windows.
Эти команды служат для завершения работы или перезагрузки DAQ-системы, программы CRW
или операционной системы Windows. Указание звука sound и задержек delay необязательно.
Если пропущен звук, то команды выполнются без звука. Если пропущены задержки, то для них будет использовано
значение по умолчанию. Например, 30 секунд - задержка по умолчанию для завершения Windows.
Пример:
@Shutdown Daq Exit Bye - Exit DAQ system with sound Bye
@Shutdown Daq Restart Gong 2 1 - Restart DAQ system, with sound Gong, with delay 2 sec, and enforce start
@Shutdown Crw Exit Bye - Exit CRW program, with sound Bye
@Shutdown Win Exit Bye 30 - Exit Windows, with sound Bye, after delay 30 sec
@Shutdown Win Logout Bye 30 - Logout Windows, with sound Bye, after delay 30 sec
@Shutdown Win Restart Bye 30 - Restart Windows, with sound Bye, after delay 30 sec
- @IfDirExists dir cmd - выполнить команду cmd, если каталог dir СУЩЕСТВУЕТ.
- @IfNotDirExists dir cmd - выполнить команду cmd, если каталог dir НЕ СУЩЕСТВУЕТ.
- @IfFileExists file cmd - выполнить команду cmd, если файл file СУЩЕСТВУЕТ.
- @IfNotFileExists file cmd - выполнить команду cmd, если файл file НЕ СУЩЕСТВУЕТ.
- @IfProcessExists exe cmd - выполнить команду cmd, если процесс exe СУЩЕСТВУЕТ.
- @IfNotProcessExists exe cmd - выполнить команду cmd, если процесс exe НЕ СУЩЕСТВУЕТ.
- @IfComputerName host cmd - выполнить команду cmd, если имя компьютера РАВНО host.
- @IfNotComputerName host cmd - выполнить команду cmd, если имя компьютера НЕ РАВНО host.
Эти команды служат для условного исполнения других команд по условиям существования файлов, каталогов или процессов.
Следует учесть, что dir, file, exe заданы в URL-кодировке.
Например, каталог "C:\Program%20Files" - это "C:\Program Files".
Пример:
@IfNotDirExists ..\Temp @MkDir ..\Temp
@IfDirExists ..\Temp @Information Directory ..\Temp exists!
@IfNotProcessExists defrag.exe @Run -hide cmd /c defrag.exe %SystemDrive% -f -v
@IfProcessExists defrag.exe @Information Defrag process started!
@IfComputerName alidcscom252 @Warning It's PHOS cooling plant server!
@IfNotComputerName alidcscom252 @Warning It's not PHOS cooling plant server!
- @MkDir dir - создать каталог dir.
- @FileErase fname - удалить файл fname.
- @FileCopy src dst - копировать файл src в файл dst.
- @FileRename src dst - переименовать(переместить) файл src в файл dst.
- @FileWriteln fname data - записать в конец файла fname строку data.
- @FileOpenDialog fmask - открыть диалог "Открыть файл" с начальным именем файла fmask.
Это группа базовых функций работы с каталогами и файлами, полезная для организации Cron-скриптов.
Следует заметить, что все имена каталогов и файлов (dir, fname, src, dst, fmask) заданы
в URL-кодировке, а также поддерживают короткие ссылки (относительные пути),
принятые в DAQ-системе.
Пример:
@IfNotDirExists ..\Temp @MkDir ..\Temp
@IfFileExists ..\Temp\F2.txt @FileErase ..\Temp\F2.txt
@IfFileExists ..\Temp\F1.txt @FileRename ..\Temp\F1.txt ..\Temp\F2.txt
@IfFileExists ..\Temp\F1.txt @FileCopy ..\Temp\F1.txt ~~\Temp\F1.txt
@FileOpenDialog C:\Program%20Files\Common%20Files\CRW-DAQ\Resource\DimSite\dim\bin\*.exe
@FileOpenDialog ~~\Temp\*.ini
@FileWriteln ..\Temp\Demo.log Задание выполнено!
- DevMsg &dev msg - послать сообщение msg устройству &dev синхронно (с пробуждением приемника).
- DevSend &dev msg - послать сообщение msg устройству &dev синхронно (с пробуждением приемника).
- DevPost &dev msg - послать сообщение msg устройству &dev асинхронно (без пробуждения приемника).
- DevSendMsg &dev msg - послать сообщение msg устройству &dev синхронно (с пробуждением приемника).
- DevPostMsg &dev msg - послать сообщение msg устройству &dev асинхронно (без пробуждения приемника).
Эти команды позволяют инициировать действия, которые выполняют другие программные устройства.
Эти команды также позволяет четко разделить функции календаря, которые исполняет &CronSrv,
и содержательные действия, которые должны выполняться по календарю. Допустим, какое-то действие
должно выполняться как по календарным событиям, так и по некоторым программным условиям.
В этом случае есть смысл выделить эти действия в отдельную программу, сделать для них
обработчик сообщений и инициировать эти действия посылкой сообщений DevSend
со стороны &CronSrv или других программ.
Пример:
@DevPostMsg &SpeakSrv @Speak Hello, world!
@DevSendMsg &DatSrv @Awake
- @Guard.HomeDir - домашний каталог запускаемой посмертно программы. См. CronGiard.
- @Guard.AppName - имя запускаемой посмертно программы. См. CronGiard.
- @Guard.CmdLine - параметры командной строки передаваемой этой программе. См. CronGiard.
- @Guard.Period - период патрулирования (проверки состояния охраняемой программы), ms. См. CronGiard.
- @Guard.Display - способ отображения окна запускаемой программы (0 - скрытно). См. CronGiard.
- @Guard.Start - начать процесс охраны работающей программы. См. CronGiard.
- @Guard.Stop - завершить процесс охраны работающей программы. См. CronGiard.
- @DebugFlags n - задать флаги отладочного вывода.
- 1 - показывать сообщения об ошибках.
- 2 - показывать информационные сообщения.
- 4 - показывать исходящий трафик.
- 8 - показывать входящий трафик.
- 16 - показывать детали (подробности).
- @Help - выдать в консоль справку по командам &CronSrv.
- @task_init n [c] - инициализация задачи с именем (n) и (необязательно) командной строкой (c).
- @task_free n - освобождение (уничтожение) задачи с именем (n).
- @task_ctrl n p - чтение параметра (p) для задачи с именем (n).
- @task_ctrl n p=v - задание значения (v) параметра (p) для задачи с именем (n).
- @task_view n - отображение (печать) параметров для задачи с именем (n) или для всех задач (при n = *).
- @task_run n - запуск на выполнение (ссоздание процесса) для задачи с именем (n).
- @task_kill n h c t - завершение процесса методом (h) с кодом возврата (c) и таймаутом (t) для задачи с именем (n).
- @task_poll n p g - задание периода опроса (p) и периода сторожа (g) для задачи с именем (n).
- @task_send n m - посылка сообщения или команды (m) в консоль StdIn процесса задачи с именем (n).
- @task_recv n c - задает шаблон команды (c) обработки консоли StdOut процесса задачи с именем (n).
Эта группа команд (@task_xxx) связана со службой задач (task), т.е. дочерних (ведомых) процессов,
работающих под управлением сервера &CronSrv для выполнения каких-то вспомогательных действий.
При этом сервер &CronSrv работает как супервизор, запускающий, завершающий и контролирующий работу
дочерних процессов.
При этом задачи идентифицируются по имени задачи (которая не обязательно совпадает с именем процесса).
Служба задач дает прикладному программисту простой и надежный способ запуска, завершения и отказоустойчивого
контроля вспомогательных процессов, которые должны запускаться/завершаться вместе с АСУ и работать в
её составе как параллельно выполняемые вспомогательные процессы.
Работа со службой задач происходит следующим образом.
- Сначала командой @task_init n создается задача с выбранным именем (n).
При создании задачи можно указать также командную строку,
либо командная строка задается позже вызовом @task_ctrl n CmdLine = c.
- Затем командами @task_ctrl n p=v задаются параметры (p=v) задачи,
в частности, можно задавать такие параметры:
CmdLine (командная строка для запуска процесса);
HomeDir (рабочий каталог процесса);
Display (способ отображения окна процесса 0=Hide,1=Show,...);
Priority (приоритет процесса 4/8/13/24=Idle/Normal/High/Realtime);
CodePage (кодировка символов процесса, например 1251=ANSI-RUSSIAN, 866=OEM-RUSSIAN);
StdInPipeSize (размер буфера StdIn в байтах);
StdOutPipeSize (размер буфера StdOut в байтах).
- Затем созданная задача запускается командой @task_run n.
Перед запуском все параметры задачи должны быть заданы.
- Для наблюдения состояния задач и их параметров можно использовать команду @task_view n
с именем интересующей задачи (n), либо n=* для отображения состояния всех задач.
- Для опроса и контроля дочерних процессов надо использовать команду @task_poll n p g,
которая задает задаче (n) период таймера опроса (p) и таймер сторожа (g).
Таймеры задаются в миллисекудах, при этом ноль означает отключение таймера.
Таймер опроса задает период опроса консоли StdOut.
Таймер сторожа задает период проверки статуса процесса для его возможного перезапуска.
Если сторож обнаруживает, что процесс не работает, то он перезапускает процесс.
Это нужно для того, чтобы обеспечить отказоустойчивую работу систем, в составе которых работает много процессов.
- Для посылки задачам сообщений или команд в консоль StdIn процесса служит команда @task_send n m,
где задается имя задачи (n) и текст сообщения (m).
С помощью посылки таких команд можно понуждать дочерние процессы выполнять нужные действия.
- Для приема от задач сообщений или команд из консоли StdOut процесса и их обработки служит команда @task_recv n c,
где задается имя задачи (n) и шаблон команды для обработки сообщения (c).
При получении данных в шаблоне команды (c) выполняется подстановка полученных данных на место строки $*.
После этого команда выполняется в локальной консоли сервера &CronSrv.
Шаблон команды должен подходить под формат команды, например:
@devpost &TargetDevice @received $*
- Для завершения процессов используется команда @task_kill n h c t,
в которой задается метод завершения (h),
код завершения (c) и время ожидания (t) в миллисекундах.
Завершение процесса не означает освобождение (уничтожение) задачи.
Процесс для данной задачи может быть перезапущен.
- Для окончательного освобождения (уничтожения) задачи используется команда @task_free n,
в результате которой задача уничтожается и удаляется из списка задач.
Для более подробной справки можно использовать справку по функциям DaqPascal
task_xxxx,
на которых основаны одноименные команды.
Пример конфигурирования задач:
;--- Пример, демонстрирующий работу службы задач (task),
;--- т.е. ведомых процессов, работающих под управлением Cron.
[&CronSrv.StartupScript] ; Действия по инициализации задач:
@task_init test1 ; Инициализация задачи (без задания командной строки)
@task_ctrl test1 CmdLine = cmd /k title test1 ; Задание командной строки
@task_ctrl test1 HomeDir = %Temp% ; Задание рабочего каталога
@task_ctrl test1 Display = 0 ; Задание режима отображения 0=Hide,1=Show
@task_ctrl test1 Priority = 8 ; Задание приоритета процесса 4/8/13/24 = Idle/Normal/High/Realtime
@task_ctrl test1 CodePage = 866 ; Задание кодовой страницы 866 = OEM RUSSIAN
@task_ctrl test1 StdInPipeSize = 1024*32 ; Размер буфера StdIn, bytes
@task_ctrl test1 StdOutPipeSize = 1024*32 ; Размер буфера StdOut, bytes
@task_poll test1 100 10000 ; Период опроса (100 ms) и сторожа (10000 ms)
@task_run test1 ; Запуск задачи на выполнение
@task_send test1 ver ; Послать задаче сообщение (выполнить команду)
@task_recv test1 @SysEval @silent @echo test1: $* ; Шаблон обработки поступающих из StdOut данных
;--------------------------------------------------
@task_init test2 cmd /k title test2 ; Инициализация задачи (с заданием командной строки)
@task_ctrl test2 HomeDir = %Temp% ; Задание рабочего каталога
@task_ctrl test2 Display = 0 ; Задание режима отображения 0=Hide,1=Show
@task_ctrl test2 Priority = 8 ; Задание приоритета процесса 4/8/13/24 = Idle/Normal/High/Realtime
@task_ctrl test2 CodePage = 866 ; Задание кодовой страницы 866 = OEM RUSSIAN
@task_ctrl test2 StdInPipeSize = 1024*32 ; Размер буфера StdIn, bytes
@task_ctrl test2 StdOutPipeSize = 1024*32 ; Размер буфера StdOut, bytes
@task_poll test2 100 10000 ; Период опроса (100 ms) и сторожа (10000 ms)
@task_run test2 ; Запуск задачи на выполнение
@task_send test2 ver ; Послать задаче сообщение (выполнить команду)
@task_send test2 ping localhost ; Послать задаче сообщение (выполнить команду)
[]
[&CronSrv.FinallyScript] ; Действия по завершению задач:
@task_kill test1 1 0 1000 ; Завершить задачу методом 1 (WM_CLOSE) с ожиданием 1000 ms
@task_kill test1 0 0 1000 ; Завершить задачу методом 0 (Terminate) с ожиданием 1000 ms
@task_free test1 ; Освободить задачу
@task_kill test2 1 0 1000 ; Завершить задачу методом 1 (WM_CLOSE) с ожиданием 1000 ms
@task_kill test2 0 0 1000 ; Завершить задачу методом 0 (Terminate) с ожиданием 1000 ms
@task_free test2 ; Освободить задачу
@task_free * ; Освободить все задачи
[]
При использовании службы задач следует помнить, что команды &CronSrv всегда доступны
любым программам DaqPascal - либо через процедуру Cron(), либо через стандартную команду @Cron,
либо (в конечном счете) через прямую посылку сообщения в консоль &CronSrv.
Поэтому использовать сервис службы задач можно из любой программы DaqPascal.
К началу
CRON-утилиты
Для решения типичных задач обслуживания систем с помощью команды @Run
к серверу &CronSrv прилагается несколько утилит:
- CronDefrag.bat d - запустить программу дефрагментации дисков defrag.exe
для списка дисков d. Если список не указан, запускается дефрагментация для системного
диска (%SystemDrive%), диска расположения Crw32.exe и диска расположения DAQ
конфигурации.
Основным назначением утилиты является периодическое обслуживание дисковой системы для предотвращения
деградации производительности дисковой системы из-за дефрагментации.
При запуске дефрагментации полезно проверить, не запущен ли уже процесс дефрагментации defrag.exe,
а также можно выполнять разные действия в зависимости от имени компьютера.
Опция @Run -hide позволит не изнурять оператора лицезрением процесса дефрагментации.
Опция @Run -lower позволит запускать процесс дефрагментации с низким приоритетом, чтобы не мешал измерениям.
Например:
;--- В полдень каждую пятницу запускать дефрагментацию дисков, если она сейчас не запущена
;--- Использовать стандартную утилиту CronDefrag.bat, отчеты смотреть в ~~\Temp\CronDefrag\
@Cron.tab Defrag 0 12 * * Fri
@Cron.job Defrag @IfComputerName egp-mzvs @IfNotProcessExists defrag.exe @Run -hide -lower CronDefrag.bat
@Cron.job Defrag @IfComputerName egp-main @IfNotProcessExists defrag.exe @Run -hide CronDefrag.bat c: d: e:
Надо иметь в виду, что утилита помещает отчеты о своей работе в каталог ~~\Temp\CronDefrag.
- CronPurger.bat s1 d1 w1 s2 d2 w2 ... - запустить программу очистки дисков
purger.exe для списка s d w. Список содержит тройки s d w, имеющие
следующее значение.
- s - численный критерий отбора удаляемых файлов.
Если указано неотрицательное число, то это максимальный
размер дискового постранства, в килобайтах, которое займут после
очистки файлы данного вида. Размер можно указывать в виде формулы,
например, 1024*1024*64 означает 64 GB.
Если указано отрицательное число, то это срок давности в днях,
считая от текущей даты, после которого более старые файлы удаляются.
Читильщик при работе удаляет наиболее старые по дате модификации файлы,
пока удовлетворяется заданный критерий отбора, чтобы либо срок давности,
либо суммарный объем файлов после зачистки не превышал заданное параметром
s значение.
- d - каталог, в котором находятся файлы для зачистки.
Имя каталога может следовать соглашениям DAQ системы: если
указано относительное имя файла, то оно вычисляется относительно
каталога главного конфигурационного файла. Если указано имя,
начинающееся с ~\, то имя указано относительно домашнего каталога
текущего пользователя. Если указано имя, начинающееся с ~~\,
то имя указано относительно домашнего каталога Crw32.exe.
Файловые маски в имени каталогов не допускаются.
- w - маска файлов, например, *.DAT.
Эта маска задает файлы, которые будут зачищаться в указанном каталоге.
Предполагается, что это будут устаревшие файлы данных или журнальные файлы.
Основным назначением утилиты является чистка каталогов данных в длительно работающих
системах, чтобы избежать переполнения рабочих дисков. При этом параллельно должны быть
предприняты меры для резервного копирования необходимых данных на "большой" сервер.
При запуске чистильщика полезно проверить, не запущен ли уже процесс чистки purger.exe.
Например:
;--- В полночь каждое воскресение запускать очистку каталогов, если она сейчас не запущена
;--- Использовать стандартную утилиту CronPurger.bat, отчеты смотреть в ~~\Temp\CronPurger\
;--- В данном примере - оставлять файлы *.log в каталоге ..\Data со сроком давности не более
;--- 5 дней, а также не более 1024*1024*64 kB = 65 GB файлов *.DAT в каталоге ..\..\CRON_DATA
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Purger 0 0 * * Sun
@Cron.job Purger @IfNotProcessExists purger.exe @Run -hide CronPurger.bat -5 ..\Data *.log 1024*1024*64 ..\..\CRON_DATA *.DAT
Надо иметь в виду, что утилита помещает отчеты о своей работе в каталог ~~\Temp\CronPurger.
- CronBackup.bat s1 w1 d1 s2 w2 d2 ... - запустить программу резервного копирования данных
xcopy.exe для списка s w d. Список содержит тройки s w d, имеющие
следующее значение.
- s - Каталог "источника" (source) данных, например,
каталога данных DAQ-системы, куда сохраняются *.CRW
и *.DAT файлы.
Имя каталога может следовать соглашениям DAQ системы: если
указано относительное имя файла, то оно вычисляется относительно
каталога главного конфигурационного файла. Если указано имя,
начинающееся с ~\, то имя указано относительно домашнего каталога
текущего пользователя. Если указано имя, начинающееся с ~~\,
то имя указано относительно домашнего каталога Crw32.exe.
Файловые маски в имени каталогов не допускаются.
- w - маска резервируемых (копируемых) файлов, например, *.DAT.
Эта маска задает файлы, которые будут копироваться из каталога "источника"
в каталог "приемника". При резервировании копироваться будут только файлы,
которые либо отсутствуют в каталоге приемника, либо имеют более раннюю дату
по сравнению с источником. Это сокращает объем копирования - скопированы
будут только вновь записанные данные. Этот режим копирования хорошо подходит
для измерительных установок, где данные упорядочены по времени и пополняются
новыми файлами в процессе работы установки.
- d - каталог "приемника" (destination), в который копируются файлы.
Имя каталога может следовать соглашениям DAQ системы: если
указано относительное имя файла, то оно вычисляется относительно
каталога главного конфигурационного файла. Если указано имя,
начинающееся с ~\, то имя указано относительно домашнего каталога
текущего пользователя. Если указано имя, начинающееся с ~~\,
то имя указано относительно домашнего каталога Crw32.exe.
Файловые маски в имени каталогов не допускаются.
Основным назначением утилиты является резервное копирование файлов данных, которые
накапливаются в процессе измерений, на "большой" сервер для долговременного хранения.
При этом параллельно должны быть предприняты меры для периодической чистки каталога данных,
чтобы избежать переполнения локальных дисков. Режим копирования (копирование только
отсутствующих или обновленных файлов) выбран с учетом минимизации трафика при копировании.
При запуске копировщика полезно проверить, не запущен ли уже процесс копирования xcopy.exe.
Например:
;--- В полдень каждое воскресение запускать резервирование файлов, если оно еще не запущено
;--- Использовать стандартную утилиту CronBackup.bat, отчеты смотреть в ~~\Temp\CronBackup\
;--- В данном примере копировать файлы *.log из каталога ..\Data в каталог ..\..\BackupLog,
;--- а также файлы *.dat из каталога ..\Data в каталог ..\..\BackupDat
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Backup 0 12 * * Sun
@Cron.job Backup @IfNotProcessExists xcopy.exe @Run -hide CronBackup.bat ..\Data *.log ..\..\BackupLog ..\Data *.dat ..\..\BackupDat
Надо иметь в виду, что утилита помещает отчеты о своей работе в каталог ~~\Temp\CronBackup.
- CronPacker.bat s1 d1 w1 s2 d2 w2 ... - запустить программу упаковки файлов
gzip.exe для списка s d w. Список содержит тройки s d w, имеющие
следующее значение.
- s - опции упаковки для gzip.exe.
Должны начинаться с символа - (дефиса).
Если указаны пустые опции "-" (просто дефис), то это эквивалентно
заданию опций "по умолчанию". В текущей версии опции "по умолчанию" равны
-rvfN9, что означает:
рекурсия (recursion),
отображение подробностей (verbose),
принудительная перезапись файлов (force),
сохранение оригинального имени и даты (Name),
наивысшая степень компрессии (9).
Другие возможные опции (из набора -acdfhlLnNrtvV19), можно посмотреть, набрав
команду gzip --help.
Упаковщик при работе упаковывает файлы в одноименные архивы с расширением *.gz,
и затем удаляет оригинальные файлы. Предполагается, что оригинальные файлы уже не нужны,
а вместо них будут храниться упакованные архивы. Упаковщик целесообразно использовать
вместе с утилитами CronBackup.bat и CronPurger.
Например, задание CronBackup.bat, используется, чтобы копировать файлы данных
из каталога данных в архивный каталог.
Затем скопированные данные в архивном каталоге архивируются утилитой CronPacker.bat.
Наконец, устаревшие файлы из каталога данных удаляются утилитой CronPurger.bat.
- d - каталог, в котором находятся файлы для архивации (упаковки).
Имя каталога может следовать соглашениям DAQ системы: если
указано относительное имя файла, то оно вычисляется относительно
каталога главного конфигурационного файла. Если указано имя,
начинающееся с ~\, то имя указано относительно домашнего каталога
текущего пользователя. Если указано имя, начинающееся с ~~\,
то имя указано относительно домашнего каталога Crw32.exe.
Файловые маски в имени каталогов не допускаются.
- w - маска файлов, например, *.DAT.
Эта маска задает файлы, которые будут архивироваться в указанном каталоге.
Предполагается, что это будут файлы данных или журнальные файлы, накапливаемые
при работе системы.
Основным назначением утилиты является упаковка файлов данных в длительно работающих
системах, чтобы избежать переполнения рабочих дисков.
При запуске упаковщика полезно проверить, не запущен ли уже процесс упаковки gzip.exe.
Например:
;--- В полночь каждую пятницу запускать упаковку файлов данных, если она сейчас не запущена
;--- Использовать стандартную утилиту CronPacker.bat, отчеты смотреть в ~~\Temp\CronPacker\
;--- В данном примере - упаковать файлы *.log в каталоге ..\Data со стандартными опциями (-)
;--- а также упаковать файлы *.DAT в каталоге ..\..\CRON_DATA с заданными явно опциями
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Packer 0 0 * * Fri
@Cron.job Packer @IfNotProcessExists gzip.exe @Run -hide -lower CronPacker.bat - ..\Data *.log -rvfN9 ..\..\CRON_DATA *.DAT
Надо иметь в виду, что утилита помещает отчеты о своей работе в каталог ~~\Temp\CronPacker.
- CronDimDns.bat -d - запустить программу DIM сервера имен dns.exe
с необязательной опцией отладочного вывода -d.
Если опция не указана, DNS запускается в обычном ("тихом") режиме.
Если опция указана, то DNS запускается в отладочном режиме с выводом всех сообщений
в журнальные файлы Program Files\Common Files\CRW-DAQ\Resource\DimSite\dim\bin\*.log.
При запуске сервера имен DNS.EXE надо обязательно проверить, не запущен ли уже процесс
DNS.EXE, чтобы избежать запуска двух копий сервера.
Например:
;--- Каждую минуту проверять наличие процесса DNS.EXE. Если он не запущен, стартовать DNS в
;--- отладочном режиме (-d), отчеты смотри в Common Files\CRW-DAQ\Resource\DimSite\dim\bin\
;--- Использовать стандартную утилиту CronDimDns.bat, отчеты смотреть в ~~\Temp\CronDimDns\
@Cron.tab DimDns *
@Cron.job DimDns @IfNotProcessExists dns.exe @Run -hide CronDimDns.bat -d
Надо иметь в виду, что утилита помещает отчеты о своей работе в каталог ~~\Temp\CronDimDns.
К началу
CRON-формат
Сервер &CronSrv использует Cron-формат для описания времени наступления календарных событий.
Cron-формат - это простой, но мощный и гибкий способ описания времени и периодичности действий в терминах
календарного времени. Он используется в аргументах команды @cron.tab.
Прототипом Cron-формата был традиционный, унаследованный из мира Unix, формат программы Cron,
который состоит из пяти полей, разделенных пробелами:
<Минуты> <Часы> <Дни_месяца> <Месяцы> <Дни_недели>
Сервер &CronSrv может работать и с традиционным, и с "улучшенным" вариантом Cron-формата,
который отличается от традиционного шестым добавленным полем - <Годы>:
<Минуты> <Часы> <Дни_месяца> <Месяцы> <Дни_недели> <Годы>
Отличием "улучшенного" варианта является также наличие символов - заменителей, которые можно
использовать для обозначения минут, часов, дней, месяцев, дней недели и лет для специальных
моментов времени:
- @ - текущее время.
- ? - время старта &CronSrv.
- # - TimeBase, обычно совпадает с временем старта DAQ-системы.
Вот схема формата:
1 2 3 4 5 6 Номер поля 1 2 3 4 5 6 Field index
* * * * * * * * * * * *
| | | | | | | | | | | |
| | | | | +--- Годы (диапазон: 1-9999) | | | | | +--- Years (range: 1-9999)
| | | | +----- Дни недели (диапазон: 1-7) | | | | +----- Week days (range: 1-7)
| | | +------- Месяцы (диапазон: 1-12) | | | +------- Month (range: 1-12)
| | +--------- Дни месяца (диапазон: 1-31) | | +--------- Month days (range: 1-31)
| +----------- Часы (диапазон: 0-23) | +----------- Hours (range: 0-23)
+------------- Минуты (диапазон: 0-59) +------------- Minutes (range: 0-59)
Для формирования полей можно использовать следующие правила:
- Число полей может меняться от 0 до 6.
Отсутствующие поля заменяются символом * (звездочка).
- Любое из шести полей может содержать список элементов, разделенных запятыми.
Пробелы или табуляции в списке элементов запрещены.
- В качестве элемента в списке допускается использовать:
- Числовое значение. Например: 1,3,7.
- Интервал (поддиапазон) значений, обозначаемый дефисом. Например: 1-5,10-15.
Концы интервала включаются в диапазон значений.
- Символ * (Asterisk), который означает полный диапазон возможных значений,
например, каждая минута, каждый час и т. д.
- Символ @ (Commercial at), который обозначает текущее время.
- Символ ? (Question mark), который обозначает время старта &CronSrv.
- Символ # (Number sign), который обозначает время TimeBase,
обычно это время старта DAQ.
- После элемента (символа *, @, ?, #, числового значения или интервала) можно также
с помощью символа / (слеш) указать шаг значений.
При этом:
- Запись */k означает "каждый k-й, начиная с 0-го".
Например, */3 означает 0,3,6,9,....
- Запись n/k означает "каждый k-й, начиная с n-го".
Например, 5/3 означает 5,8,11,14,17,....
- Запись n-m/k означает "каждый k-й, начиная с n-го, но не более чем m".
Например, 5-11/3 означает 5,8,11.
Например, 0-12/2 может использоваться в поле "Часы" для указания того,
что действие должно происходить каждые два часа до полудня (альтернатива списка - 0,2,4,6,8,10,12).
Или, например, значение */4 в поле "Минуты" означает, что действие, должно происходить каждые четыре минуты.
А запись, например, 1-15/3 - это то же, что и 1,4,7,10,13.
- В полях "Дни недели" можно вместо числовых значений использовать названия дней недели,
полные или сокращенные до двух или трех согласных букв, на русском и английском языке:
1 Mo, Mon, Monday, Пн, Пнд, Понедельник,
2 Tu, Tue, Tuesday, Вт, Втр, Вторник,
3 We, Wed, Wednesday, Ср, Срд, Среда,
4 Th, Thu, Thursday, Чт, Чтв, Четверг,
5 Fr, Fri, Friday, Пт, Птн, Пятница,
6 Sa, Sat, Saturday, Сб, Сбт, Суббота,
7 Su, Sun, Sunday, Вс, Вск, Воскресенье.
- В полях "Месяцы" можно вместо числовых значений использовать имена названия месяцев,
полные или сокращенные до трех букв, на русском и английском языке:
1 Jan, January, Янв, Январь,
2 Feb, February, Фев, Февраль,
3 Mar, March, Мар, Март,
4 Apr, April, Апр, Апрель,
5 May, May, Май, Май,
6 Jun, June, Июн, Июнь,
7 Jul, July, Июл, Июль,
8 Aug, August, Авг, Август,
9 Sep, September, Сен, Сентябрь,
10 Oct, October, Окт, Октябрь,
11 Nov, November, Ноя, Ноябрь,
12 Dec, December, Дек, Декабрь.
При задании графика событий следует учитывать, что, если в момент создания задания
календарное условие уже выполнено, то данное событие НЕ ИСПОЛНЯЕТСЯ, пока не наступит следующее
событие, удовлетворяющее этому условию.
Например, если задать условие [ * ] (выполнять каждую минуту), то соответствующее задание будет вызвано
только после смены текущей минуты, хотя формально условие выполняется для любого момента времени.
Или, например, задание [ @ @ ] (выполнять каждый день в текущее время суток) будет выполнено
только через сутки, хотя в текущий момент условие уже выполнено. Это правило позволяет избежать
преждевременного исполнения заданий. В конце концов, никто не мешает исполнить задание немедленно,
вызвав команду @cron.run, если это так необходимо.
Примеры:
| Cron-формула |
Расшифровка |
| * |
Каждую минуту. |
| * * * * * * |
Каждую минуту. |
| 0 8 |
Каждое утро в 08:00. |
| 0 8 * * Mon-Fri |
Каждое утро в 08:00 по рабочим дням. |
| 0 8 */2 |
Каждое утро в 08:00 по четным дням месяца. |
| 0 8 1/2 |
Каждое утро в 08:00 по нечетным дням месяца. |
| 0 8 * Mar-May |
Каждое утро в 08:00 весной (март,апрель,май). |
| 45-59/3 16 * * Пн-Чт |
Каждые 3 минуты начиная с 16:45 до 17:00, с понедельника по четверг. Например, напоминание о конце рабочего дня. |
| 45-59/3 15 * * Fri |
Каждые 3 минуты начиная с 15:45 до 16:00, в пятницу. Например, напоминание о конце рабочей недели. |
| 0 0 * * Sun |
В полночь каждое воскресенье. |
| 59 23 31 Dec |
За минуту до конца года. |
| 59 23 31 Dec Fri |
За минуту до конца года, если последний день года - пятница. |
| 0-30/3,30-59/5 * * * Mon |
Каждую третью минуту в течение первых 30 минут каждого часа, затем каждую пятую минуту до конца каждого часа, в понедельник. |
| 0 0 1 |
В полночь, первого числа каждого месяца. |
| 0 9 1-7 * Mon |
Первый понедельник каждого месяца, в 9 утра. |
| 0 12 * * * @ |
Каждый полдень текущего года. |
| 0 ? |
Каждый день в начале часа, когда стартовал &CronSrv. |
| 0 # |
Каждый день в начале часа, соответствующего TimeBase. |
К началу
Примеры Cron-скрипов
Здесь приводятся типовые примеры скриптов для сервера &CronSrv,
в качестве прототипиров, предназначенных для создания собственных скриптов.
;---Включить сервер &CronSrv в конфигурацию.
[ConfigFileList]
ConfigFile = ~~\Resource\DaqSite\CronServer\CronSrv.cfg
[]
;--- Стартовая секция сервера &CronSrv. Выполняется при запуске сервера.
;--- Здесь можно поместить создание заданий, установку размеров окон и т.д.
[&CronSrv.StartupScript]
; Задать "тихий" режим вычислений
@SilentEval 1
;--- Задать режим консольного вывода для отладки
;--- Вывести в консоль справку по командам &CronSrv
@DebugFlags 15
@Help
;--- Каждое утро в 8:00 ударять в гонг и говорить приветствие
@Cron.tab DailyMorning 0 8
@Cron.job DaylyMorning @Voice Gong
@Cron.job DailyMorning @Speak Доброе утро, сейчас 8:00.
;--- Выполнить задание один раз, разместив в конце задания
;--- асинхронную (!) команду его удаления после исполнения
;--- Выдать на 15 секунд окно с текстом "RunOnce - это .."
;--- Потом запустить утилиту ..\Utility\RunOnce.bat, старт
;--- выполнять в каталоге ~~\Temp. Обращу внимание - чтобы
;--- эта утилита была доступна,надо указать в секции [DAQ]
;--- путь поиска SearchPath = ..\Utility,или можно вызвать
;--- как %CRW_DAQ_CONFIG_DATA_PATH%\..\Utility\RunOnce.bat
@Cron.tab RunOnce *
@Cron.job RunOnce @Run -hide msg.exe * /time:15 "RunOnce - это задание, выполняемое один раз, после старта."
@Cron.job RunOnce @Run -hide -cd Temp cmd /c RunOnce.bat
@Cron.job RunOnce @Async @Cron.del RunOnce
;--- Каждую минуту проверять наличие процесса DNS.EXE. Если он не запущен, стартовать DNS в
;--- отладочном режиме (-d), отчеты смотри в Common Files\CRW-DAQ\Resource\DimSite\dim\bin\
;--- Использовать стандартную утилиту CronDimDns.bat, отчеты смотреть в ~~\Temp\CronDimDns\
@Cron.tab DimDns *
@Cron.job DimDns @IfNotProcessExists dns.exe @Run -hide CronDimDns.bat -d
;--- В полдень каждую пятницу запускать дефрагментацию дисков, если она сейчас не запущена
;--- Использовать стандартную утилиту CronDefrag.bat, отчеты смотреть в ~~\Temp\CronDefrag\
@Cron.tab Defrag 0 12 * * Fri
@Cron.job Defrag @IfNotProcessExists defrag.exe @Run -hide CronDefrag.bat
;--- В полночь каждое воскресение запускать очистку каталогов, если она сейчас не запущена
;--- Использовать стандартную утилиту CronPurger.bat, отчеты смотреть в ~~\Temp\CronPurger\
;--- В данном примере оставлять файлы *.log в каталоге ..\Data со сроком давности не более
;--- 5 дней, а также не более 1024*1024*64 kB = 65 GB файлов *.DAT в каталоге ..\..\CRON_DATA
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Purger 0 0 * * Sun
@Cron.job Purger @IfNotProcessExists purger.exe @Run -hide CronPurger.bat -5 ..\Data *.log 1024*1024*64 ..\..\CRON_DATA *.DAT
;--- В полдень каждое воскресение запускать резервирование файлов, если оно еще не запущено
;--- Использовать стандартную утилиту CronBackup.bat, отчеты смотреть в ~~\Temp\CronBackup\
;--- В данном примере копировать файлы *.log из каталога ..\Data в каталог ..\..\BackupLog,
;--- а также файлы *.dat из каталога ..\Data в каталог ..\..\BackupDat
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Backup 0 12 * * Sun
@Cron.job Backup @IfNotProcessExists xcopy.exe @Run -hide CronBackup.bat ..\Data *.log ..\..\BackupLog ..\Data *.dat ..\..\BackupDat
;--- В полночь каждую пятницу запускать упаковку файлов данных, если она сейчас не запущена
;--- Использовать стандартную утилиту CronPacker.bat, отчеты смотреть в ~~\Temp\CronPacker\
;--- В данном примере - упаковать файлы *.log в каталоге ..\Data со стандартными опциями (-)
;--- а также упаковать файлы *.DAT в каталоге ..\..\CRON_DATA с заданными явно опциями
;--- Для имен каталогов действуют обычные правила DAQ - относительные имена вычисляются от
;--- файла конфигурации, работают также ссылки ~\ и ~~\
@Cron.tab Packer 0 0 * * Fri
@Cron.job Packer @IfNotProcessExists gzip.exe @Run -hide -lower CronPacker.bat - ..\Data *.log -rvfN9 ..\..\CRON_DATA *.DAT
;--- Создать задание, но не календарное (указать недопустимое время 0 0 0)
;--- Стартовать Pulser с периодом 10000 ms, без счетчика. Каждые 10 секунд
;--- он будет выдавать в консоль статистику использования процессора CPU,%
@cron.tab Every10Sec 0 0 0
@cron.pul Every10Sec 10000 -
@cron.job Every10Sec @cron.cpu
;--- Создать задание, но не календарное (указать недопустимое время 0 0 0)
;--- Стартовать Pulser с периодом 15000 ms, со счетчиком повторения 10 раз
;--- Каждые 15 секунд 10 раз будет выдан звук done1
@cron.tab TenTimes 0 0 0
@cron.pul TenTimes 15000 10
@cron.job TenTimes @Voice done1
;--- Задание по дефрагментации системного диска и диска расположения Crw32.exe, которое никогда не выполняется
;--- по расписанию, так как указано недопустимое время, но которое можно использовать как готовую подпрограмму
;--- Поскольку действия не тривиальные и не могут быть сделаны одной командной строкой, то создается временный
;--- командный файл ~~\Temp\Defrag\Defrag.bat, в него записывается нужный набор команд, и затем он исполняется
@Cron.tab SysDefrag 0 0 0 0 0 0
@Cron.job SysDefrag @IfNotDirExists ~~\Temp\Defrag @MkDir ~~\Temp\Defrag
@Cron.job SysDefrag @IfFileExists ~~\Temp\Defrag\Defrag.bat @FileErase ~~\Temp\Defrag\Defrag.bat
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat ..\..\Resource\Tools\Purger\Purger.exe -raw 512 *.log
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat set log=%Date:~6,4%%Date:~3,2%%Date:~0,2%-Defrag.log
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat for %%D in (%SystemDrive% %cd:~0,2%) do (
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat @echo. >> %log% && @echo. >> %log%
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat @echo %Date%-%Time% - defrag.exe %%D -f -v >> %log%
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat defrag.exe %%D -f -v >> %log%
@Cron.job SysDefrag @FileWriteln ~~\Temp\Defrag\Defrag.bat )
@Cron.job SysDefrag @IfFileExists ~~\Temp\Defrag\Defrag.bat @IfNotProcessExists defrag.exe @Run -hide -cd Temp\Defrag cmd /c Defrag.bat
;--- В полдень каждое воскресенье запускать дефрагментацию системного диска,
;--- если она еще не запущена; выдавать отчет в каталог Crw32exe\Temp\Defrag
@Cron.tab Defrag 0 12 * * Sun
@Cron.job Defrag @IfNotProcessExists defrag.exe @Cron.run SysDefrag
;--- Посмотреть список созданных заданий
@cron.see
[]
;--- Завершающая секция сервера &CronSrv. Выполняется при остановке сервера.
[&CronSrv.FinallyScript]
;--- Показать ToolBar, StatusBar, окно DAQ-СИСТЕМА
@ShowMainToolBar 1
@ShowMainStatusBar 1
@ShowMainDaqControl 1
;--- Показать окно ГЛАВНАЯ КОНСОЛЬ и задать его положение
@WinShow ГЛАВНАЯ КОНСОЛЬ
@WinDraw ГЛАВНАЯ КОНСОЛЬ|Left=367|Top=0|Width=600|Height=317
@WinSelect ГЛАВНАЯ КОНСОЛЬ
[]
К началу
"Защитник" CronGuard, или "Ванька-Встанька"
Cервер &CronSrv может заставить программу работать в "непотопляемом" режиме,
в котором она перезапускается (или запускает другую программу) в случае своей "смерти".
Работает это так.
Пишем "завещание" программе "охраны" CronGrd.exe.
Что-то вроде "в случае моей смерти прошу выполнить мое последнее желание".
То есть задаем командами параметры "охраны":
- @Guard.HomeDir - домашний каталог запускаемой "посмертно" программы,
- @Guard.AppName - имя запускаемой "посмертно" программы,
- @Guard.CmdLine - параметры командной строки передаваемой этой программе,
- @Guard.Period - период "патрулирования" (ms), т.е. проверки состояния охраняемой программы,
- @Guard.Display - способ отображения окна запускаемой "посмертно" программы (0 - скрытно),
- @Guard.Start - начать процесс "охраны" работающей программы,
- @Guard.Stop - завершить процесс "охраны" работающей программы.
После выполнения команды старта "охраны" запускается процесс - "охранник" CronGrd.exe.
Он начинает "патрулировать", то есть следить, не "умер" ли его "хозяин" - основной процесс Crw32.exe.
Если он "умер", то "охранник" выполняет "завещание", т.е. запускает указанную ему "посмертную"
программу в указанном каталоге с указанными параметрами, после чего завершает работу.
Если "хозяин" умер и "завещание" исполнено - "служба" закончена.
В качестве "завещания" ("посмертной" программы) можно указать перезапуск пакета ( например,
указав ~~\CrwGo.exe ) и передать ему имя текущего основного конфигурационного файла,
чтобы "посмертно" произошел перезапуск текущей конфигурации.
При указании каталога @Guard.HomeDir и имени программы @Guard.AppName, а также
параметров командной строки @Guard.CmdLine допустимо использовать относительные ссылки:
- .\ - каталог основной конфигурации,
- ..\ - родительский каталог основной конфигурации,
- ~\ - домашний каталог пользователя,
- ~~\ - домашний каталог основной программы Crw32.exe,
как это принято в DAQ.
При указании параметров командной стоки допустимо также использовать символы - заместители:
- %* - список текущих аргументов командной строки, эквивалентно %1 %2 %3 %4 %5 %6 %7 %8 %9.
- %1 - 1-й аргумент командной строки, с которой запущена программа.
- %2 - 2-й аргумент командной строки, с которой запущена программа.
- %3 - 3-й аргумент командной строки, с которой запущена программа.
- %4 - 4-й аргумент командной строки, с которой запущена программа.
- %5 - 5-й аргумент командной строки, с которой запущена программа.
- %6 - 6-й аргумент командной строки, с которой запущена программа.
- %7 - 7-й аргумент командной строки, с которой запущена программа.
- %8 - 8-й аргумент командной строки, с которой запущена программа.
- %9 - 9-й аргумент командной строки, с которой запущена программа.
Использование этих заместителей позволяет перезапускать пакет с теми же аргументами,
с какими запущен пакет. Это особенно удобно для организации систем, автоматически
запускаемых из "Автозагрузки" или с использованием специального ярлыка,
где все нужные параметры уже прописаны.
Чтобы сделать "непотопляемую" систему контроля, мало перезапустить измерительную конфигурацию.
Надо также позаботиться о том, чтобы она автоматически стартовала после загрузки ([DAQ] AutoStart = 1 ).
Кроме того, программа в этом случае должна сохранять свои критические параметры на жестком диске,
например, в .INI - файле, чтобы при старте продолжить прерванную работу в правильном состоянии.
Кроме того, надо вставить ярлык на запуск конфигурации в "Автозагрузку", чтобы при аварийном перезапуске
операционной системы измерительная конфигурация также автоматически перезапускалась.
Это предотвратит остановку контроля при сбое по питанию, например.
Построенная таким образом система контроля будет подобна русской игрушке - "Ваньке-Встаньке", который
после любого "падения" все равно встает в нужное положение.
Пример:
[&CronSrv.StartupScript]
@Guard.HomeDir=~~\ ; Запускать в своем рабочем каталоге
@Guard.AppName=~~\CrwGo.exe ; Запускать самого себя - перезапуск пакета
@Guard.CmdLine=/Icon=1 .\!DEMO.CFG ; Запускать указанный конфигурационный файл
@Guard.CmdLine=%1 %2 %3 %4 %5 %6 %7 ; Другой вариант - взять аргументы, с которыми запущена основная программа
@Guard.Period=15000 ; Патрулировать каждые 15 сек
@Guard.Display=0 ; Запускать CrwGo скрытно
@Guard.Start ; Начать охрану
[]
[&CronSrv.FinallyScript]
@Guard.Stop ; Необходимо снять охрану, иначе будет перезапуск
[]
К началу