Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: Unix cron scheduler
Ron Laird 11-09-99
Documentation for Winbatch Cron version 1.8 November 08, 1998 This program implements a scheduler similar to UNIX Cron. It uses for input a file called 'crontab.txt' and for logging it produces a file called 'cronlog.txt'. This program is hardcoded to use as its home 'c:\cron'. Through testing I have determined this the best location. A typical installation would call for a directory called 'cron' on drive 'c:' with a subdirectory called 'scripts'. WBCron can run a program from anywhere, but DOES NOT set the default directory. It is up to the executing program or script to set their own default directory at runtime. When WBCron is started it goes through an initialization and then waits until the next full minute at 00 seconds before any scheduled jobs are run. This ensures that all jobs are evaluated on the minute. On the minute WBCron check the timestamp on the 'crontab.txt file'. If the file has changed since the last minute it rereads the file, stripping out all comments. If the timestamp has not changed, jobs stored in an internal list are evaluated. The command line executed can not contain spaces. Therefore, 'c:\cron\scripts\notepad mytxt.txt' is OK, but 'c:\cron\my program\notepad text.txt' is not. You could run 'text.txt' but the associated text editor would start, which in most cases is notepad. This limitation is due to my use of the 'ParseData (line)' function in WinBatch. I may change this in the future, but the ParseData data function is fast and was chosen for this reason. For scripts that I develop I don't use command line parameters. Three are three limitations with this program. 1. Ranges and specific values cannot exist in the same element. Break the schedule into two line (see examples) 2. You can only execute as many commands as can be executed in 60 seconds. WBCron needs to evaluate the schedule every 60 seconds and must sleep first. This is really not a problem since I would expect that 20 scheduled jobs or so per minute would be good enough for most anyone. I have not really seen a limitation on the number of scheduled jobs, just a limit on the number that can executed in the same minute. This also depends alot on the speed of your CPU. 3. WBCron evaluates time based on a 24 hour clock. WBCron does not support a schedule spanning midnight. The range 22-02 is not supported. Break the schedule into 22-23 and on another line 00-02. (The crontab file will be discussed below) When this program is run on a Win95 or Win98 machine it will place itself in the toolbar. It will terminate quietly when Windows shutsdown. Right clicking on the toolbar Icon will give you an option to quit cron. The option to quit will show up on the next full minute. The quickest way to make cron stop doing something is to have a shortcut to the crontab.txt file. Open the file and comment out the line in the schedule. When this program is run on an NT machine it hides itself with no icon. It is meant to be used with srvany from the NT resource kit. When run with srvany be sure to set the default run directory to c:\cron. (see the documentation that comes with srvany) All schedules that are invoked with cron log to the cronlog.txt file in the cron directory. The values minute, hour, date, month, day of week provide for a very powerful scheduling tool. If your schedules are not working as expected go back and closely examine your schedule. Comment your schedule. Comments are stripped out and do not affect the performance of cron. There is an internal keyword 'deletelog' When deletelog is scheduled it renames the cronlog.txt file to cronlog.bak. This provides a simple of way of maintaining the cron log. Use deltelog as often as you like. Installing Cron.exe Create a directory c:\cron. Copy the cron.wbt or cron.exe into the c:\cron directory. Run cron.exe at startup on win95 or win98. If running on NT cron can be started with srvany.exe A crontab.txt file must be present in the c:\cron directory for cron to run. If the crontab.txt file is not found, cron will shutdown and log an error message. For security a file based version of its schedule must be found, it is the only way to know what program cron will execute next. WARNING: Cron will execute any program you tell it to. This includes delete and format. Use cron at your own risk and only with scripts and programs that have been debugged. Crontab.txt File Format The following rules apply to the crontab file. 1. all fields are space delimited 2. all numbers are two digits 01,02,03,12,13 etc. 3. ranges can be numbers 01-10 etc and keywords Mon-Thu etc. ranges cannot span Dec and ranges cannot span Sat 4. multiple numbers within the same field are separated by ',' or '-' not both 5. The month and DayofWeek fields use words. Case is insignificant. Mon Tue Wed Thu Fri Sat Sun Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec # Crontab version 1.8 sample crontab.txt # # usage # usage [min hour date month dayofweek include\path\filename] # # A '#' sign makes it a comment # Each element is space delimited. Multiple items are separated by ','. # Ranges of items are separated by '-'. # A valid schedule consists of 6 elements separated by spaces. # All items less then 10 must have a leading zero 01,02 etc # valid key words are: # Sun Mon Tue Wed Thu Fri Sat Weekday(Mon-Fri) Weekend(Sat,Sun) # Month names Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec # # Delete and backup cronlog.txt at midnight the 1st of every month 00 00 01 * * deletelog # # Run every min every hour every month every day of the week # * * * * * notepad.exe # # Run every min every hour every month every day of the week if its Tuesday # * * * * Tue notepad.exe # # Run every weekday(Mon-Fri) at 10am # 00 10 * * weekday notepad.exe # # Specific values # Run 1,3,5,7 minutes after the hours of 10am and 11am in Aug and Nov if it is Mon or Wed # regardless of the date # 01,03,05,07 10,14 * Aug,Nov Mon,Wed notepad.exe # # Ranges of values # Run every 1,2,3,4,5,6,7 mins after the hour of 10,11,12,13,14 dur Aug,Sep,Oct,Nov only if # the 30th of the month and is Mon Tue or Wed # 01-07 10-14 30 Aug-Nov Mon-Wed notepad.exe # # Ranges and Values cannot exist in the same element 1,2,3,4-7 is unsupported at this time #
;*************************************************************************** ;** ;** Winbatch Cron ;** 17 Sep 1999 Ronald Laird ;** Purpose: Duplicate the function of Unix Cron for Win32 ;** Inputs: crontab.txt ;** Outputs: cronlog.txt ;** Revisions: 1.1 inital cut ;** 1.2 added dayofweek for param 5 ;** 1.3 added service stuff for NT ;** 1.4 added only read crontab if it changes ;** added quiet termination (intcontrol (12,5,0,0,0)) ;** 1.5 reorganized source code for readability ;** 1.6 added internal 'deletelog' command ;** 1.7 added range for day of week ;** 1.8 added range for month names ver = "Cron 1.8.1" ; initalize version number ;*************************************************************************** ; to do ; allow both range and individual events on single line ; allow spaces in command line ;*************************************************************************** ;** ;** Main Program Loop ;** ;** Purpose: All major work is done is this routine, calls all others ;** Inputs: ;** Outputs: ;** Revisions: ;*************************************************************************** gosub initalize If FileExist("crontab.txt") While(@TRUE) gosub readfile gosub gettime for i = 1 to ItemCount(internalsched,"|") line = ItemExtract (i, internalsched,"|") linecount = i ParseData (line) if param0 < 6 msg = "line %linecount% contains less than 6 parms" gosub logging Continue ; skip current sched line try next one endif ; Parse Minute Value schedminute = param1 if schedminute == "*" schedminute = computerminute else ;schedule is a range if StrIndex (schedminute, "-", 1, @FWDSCAN) != @FALSE start = ItemExtract (1, schedminute, "-") finish = ItemExtract(2, schedminute, "-") tempminute ="" for minsx = start to finish if minsx <= 9 then minsx = strcat("0","%minsx%") tempminute = ItemInsert (minsx, -1, tempminute , ",") next schedminute = tempminute if ItemLocate(computerminute, schedminute, ",") !=@FALSE then schedminute = computerminute else ;schedule is not a range if ItemLocate(computerminute, schedminute, ",") !=@FALSE then schedminute = computerminute endif endif ;Parse Hour Value schedhour = param2 if schedhour == "*" schedhour = computerhour else ;schedule is a range if StrIndex (schedhour, "-", 1, @FWDSCAN) != @FALSE start = ItemExtract (1, schedhour, "-") finish = ItemExtract(2, schedhour, "-") temphours ="" for hours = start to finish if hours <= 9 then hours = strcat("0","%hours%") temphours = ItemInsert (hours, -1, temphours , ",") next schedhour = temphours if Itemlocate(computerhour, schedhour, ",") !=@FALSE then schedhour = computerhour else ;sched is not range if Itemlocate(computerhour, schedhour, ",") !=@FALSE then schedhour = computerhour endif endif ;Parse Day Value schedday = param3 if schedday == "*" schedday = computerday else if StrIndex (schedday, "-", 1, @FWDSCAN) != @FALSE start = ItemExtract (1, schedday, "-") finish = ItemExtract(2, schedday, "-") tempdays ="" for days = start to finish if days <= 9 then days = strcat("0","%days%") tempdays = ItemInsert (days, -1, tempdays , ",") next schedday = tempdays if ItemLocate(computerday, schedday, ",") !=@FALSE then schedday = computerday else if ItemLocate(computerday, schedday, ",") !=@FALSE then schedday = computerday endif endif ;Parse Month Value schedmonth = Strupper(param4) if schedmonth == "*" schedmonth = computermonth else if ItemLocate (schedmonth, monthlist, ",") !=0 tempmonth="" mon = ItemLocate(schedmonth,monthlist, ",") if mon <= 9 then mon = strcat("0","%mon%") tempmonth = ItemInsert(mon,-1, tempmonth, ",") schedmonth = tempmonth endif if StrIndex(schedmonth, ",", 1, @FWDSCAN) !=@FALSE tempmonth ="" for months = 1 to ItemCount(schedmonth, ",") mon = ItemLocate((ItemExtract(months,schedmonth,",")),monthlist, ",") if mon <= 9 then mon = strcat("0","%mon%") tempmonth = ItemInsert(mon,-1, tempmonth, ",") next schedmonth = tempmonth endif if StrIndex(schedmonth, "-", 1, @FWDSCAN) !=@FALSE start = ItemLocate((ItemExtract(1, schedmonth, "-")), monthlist, ",") finish = ItemLocate((ItemExtract(2, schedmonth, "-")),monthlist, ",") tempmonth ="" for months = start to finish if months <= 9 then months = strcat("0","%months%") tempmonth = ItemInsert (months, -1, tempmonth, ",") next schedmonth = tempmonth endif if ItemLocate(computermonth, schedmonth, ",") !=@FALSE then schedmonth = computermonth endif ;Parse Day of Week Value schedweekday = strupper(param5) if schedweekday == "*" schedweekday = computerweekday else if StrIndex(schedweekday, "-", 1,@FWDSCAN) !=@FALSE ; schedule is a range of days ;lookup day index of fist day in range by dayname start = ItemLocate((ItemExtract(1, schedweekday, "-")), daylist, ",") ;lookup day index of second day in range by dayname finish = ItemLocate((ItemExtract(2, schedweekday, "-")), daylist, ",") tempday="" for days = start to finish if days <= 6 then days = strcat("0","%days%") ;lookup day in daylist by day number and insert dayname into tempday tempday = ItemInsert((ItemExtract(days, daylist, ",")), -1, tempday, ",") next schedweekday = tempday endif if schedweekday == "WEEKDAY" then schedweekday = "MON,TUE,WED,TUR,FRI" if schedweekday == "WEEKEND" then schedweekday = "SAT,SUN" if ItemLocate(computerweekday, schedweekday, ",") !=@FALSE then schedweekday = computerweekday endif filename = param6 ; Determine if it's time for something to run if computerminute == schedminute if computerhour == schedhour if computerday == schedday if computermonth == schedmonth if computerweekday == schedweekday ;do stuff if filename == "deletelog" gosub logbackup else errormode(@Off) runstat = run("%filename%","%param7%") errormode(@Cancel) if runstat == @TRUE msg = "run %filename% %param7% OK" gosub logging else msg = "run %filename% %param7% BAD" gosub logging endif endif ; filename endif ; schedweekday endif ; schedmonth endif ; scheday endif ; schedhour endif ; schedminute next ; line of interal schedule drop(linecount,param0,param1,param2,param3,param4,param5,param6,line) gosub sleep click = IntControl(1007, 0, 1, ver, "shell32.dll|40") if click == "2" q = AskYesNo('Cron', 'Quit Cron YES/NO?') If q == @YES msg = "%ver% Exiting" gosub logging exit endif endif EndWhile else gosub fatal endif exit ;END PROGRAM ;*************************************************************************** ;** ;** Logging Subroutine ;** ;** Purpose: Open a file and log events ;** Inputs: ;** Outputs: cronlog.txt ;** Revisions: ;*************************************************************************** :logging log = FileOpen("cronlog.txt","APPEND") FileWrite(log,"%now% %msg%") FileClose(log) return ;*************************************************************************** ;** ;** Sleep Subroutne ;** ;** Purpose: Sleep untill next full minute. Keep sleep time from drifting ;** Inputs: ;** Outputs: ;** Revisions: ;*************************************************************************** :sleep sleepuntil = TimeAdd(adjustedtime,"0000:00:00:00:01:00") ; Adds 1 minute to last time lookup TimeWait(sleepuntil) ; Waits for the next time to occur return ;*************************************************************************** ;** ;** Get Time Subroutine ;** ;** Purpose: Take system time and parse into usefull variables. ;** Inputs: ;** Outputs: ;** Revisions: ;*************************************************************************** :gettime now = TimeYmdHms ( ) computerweekday= strupper(Itemextract("1", (TimeDate()), " ")) computerminute = ItemExtract("5", now, ":") computerhour = ItemExtract("4", now, ":") computerday = ItemExtract("3", now, ":") computermonth = ItemExtract("2", now, ":") computeryear = ItemExtract("1", now, ":") adjustedtime = strcat(computeryear,":",computermonth,":",computerday, ":",computerhour,":", computerminute,":", "00") return ;*************************************************************************** ;** ;** System Type Subroutine ;** ;** Purpose: Calucalte system type and configure runtime ;** Inputs: ;** Outputs: ;** Revisions: ;*************************************************************************** :systemtype ;-4 Windows Platform; ; 0 = Other 1 = Windows 2 = Windows for Workgroups 3 = Win32s 4 = Windows NT 5 = Windows 95 or 98 osint = WinMetrics(-4) Switch osint case 0 os = "Other" break case 1 os = "Windows" break case 2 os = "Windows for Workgroups" break case 3 os = "Win32s" break case 4 os = "Windows NT" break case 5 os = "Windows 95/98" break case osint ; default case os = "UNKNOWN" break EndSwitch return ;*************************************************************************** ;** ;** Read Crontab.txt file Subroutine ;** ;** Purpose: read imput file at startup and only when it changes ;** Inputs: crontab.txt ;** Outputs: ;** Revisions: ;*************************************************************************** :readfile if fileexist("crontab.txt") == @False then gosub fatal filetime = filetimecode("crontab.txt") if oldfiletime == filetime ;read from array oldfiletime = filetime else internalsched = "" oldfiletime = filetimecode("crontab.txt") schedule = FileOpen("crontab.txt","READ") While(@TRUE) line = FileRead(schedule) if line == "*EOF*" Then Break if StrSub (line, 1, 1) == "#" then Continue internalsched = ItemInsert (line, -1, internalsched,"|") Endwhile FileClose(schedule) endif return ;*************************************************************************** ;** ;** Backup and purge logs file ;** ;** Purpose: To provide an interalfunction to kill large logfile ;** Inputs: cronlog.txt ;** Outputs: cronlog.bak ;** Revisions: ;*************************************************************************** :logbackup FileMove ("cronlog.txt", "cronlog.bak", @FALSE) msg = "Log backup occured %ver%" gosub logging return ;*************************************************************************** ;** ;** Initalize program startup ;** ;** Purpose: This subroutine is only used one at program initalization ;** Inputs: ;** Outputs: ;** Revisions: ;*************************************************************************** :initalize IntControl (12, 5, 0, 0, 0);allow quite termination of application filetime = "" ; initalize filetime timestame oldfiletime = "" ; initalize oldfile timestamp monthlist ="JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC" ; initalize month list daylist = "SUN,MON,TUE,WED,THU,FRI,SAT" ; initalize day list now = TimeYmdHms ( ) ; initalize time msg = "%ver% Started" ; initalize messages gosub systemtype if os == "Windows 95/98" then IntControl(1007, 1, 1, ver, "pifmgr.dll|14") ; run in toolbar if os == "Windows NT" IntControl (1001, 1, 0, 0, 0); run as service IntControl (1002, 0, 0, 0, 0); hide Icon endif dirchange("c:\cron") ; The cron directory is hard coded. gosub logging gosub gettime gosub sleep return :fatal if os == "Windows 95/98" Display(5,"Cron Error","crontab file not found!") endif msg = "%ver% Exiting, crontab file not found" gosub logging exit return
Article ID: W14717
Filename: Cron Scheduler - Winbatch Version.txt
File Created: 2000:09:19:16:10:18
Last Updated: 2000:09:19:16:10:18