views:

80

answers:

5

Hi guys,

I'm tryin' to find a way (from a batch file) that I can use to create a scheduled task that will execute 6 months from now. I've looked all over the net, and I'll I've come across is AT and SCHTASKS that will schedule the task monthly ..

I'm looking for a solution that will execute this task every 6 months.

I know this will require some time/date manipulation .. finding the month (number of month) and then adding 6 to it; once it passes '12' it goes back to 1 etc .. Then lining those numbers up with the months name, and using SCHTASKS or AT to schedule the task.

I know how to use SCHTASKS to schedule a task from a batch file; I just need the code to find the month, add 6 to it, grab the months name in 6 months time, and put that into a variable so I can parse it into the SCHTASKS.

I hope this all makes sense. My english is not so great.

TIA,

Greg

A: 

Why not use the Windows Scheduler?

Most of the information you need is included in this article: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true

You can use the monthly setting, with a value of 6 surely?

Dave
in the Windows Scheduler, I can select monthly, and then select the months I wish to use, so yes, I could do it that way .. but automation is the key :) Time is of the essence. Thanks for taking the time to reply Dave
Greg
No problem Greg, I /genuinely/ think this is the best way to solve this problem, on my project the team I am a member of rely solely on the windows scheduler to control tasks on daily, weekly, monthly occurences - it's been around so long that you can put 100% confidence in it, while we could try to re-invent the wheel, it's simply not worth it (in my opinion!). Also the other side of this, is that system restarts/crashes etc will not affect the schedule. I *think* I may be missing the reason why this doesn't work for you though?
Dave
Pretty much my whole tune-up is scripted (the software side of it anyway) I've worked long and hard on it, and want to keep it that way if I can. Thanks for your suggestions though.
Greg
Slightly off topic now, but why not look at writing your own windows service then? This is a very easy thing to do - a helper class with logic to control the scheduled task, a parent thread which sleeps for a minute/hour/day, and performs a simple check (IsTimeToRun for example) which would compare DateTime.Now to a stored date? Doing this in c# (again, for example) is very easy :) I hope this is food for thought :) (can give more details if necessary - I've done this personally several times).
Dave
That sounds really really complicated, and is way out of my depth. I'll sleep on it for now I think. I might have some crazy idea, and the code will just pop into my head =) These things have happened to me before.
Greg
No Problem Greg, hope you get a good solution to this and sorry I couldn't be of more help! :)
Dave
A: 

Here's a crazy idea: in case you want this script on a server (which isn't rebooted), you could write a batch file which waits for six months and then executes the given program. To wait for a specific number of seconds you could abuse the 'ping' command, like this:

ping -n %SECS% localhost > NUL

This command will effectively pause for %SECS% seconds and then return. To wait for six months, simply wait for something like (365 / 2) * 24 * 60 * 60 seconds.

Here's a little batch file which implements this idea:

@echo off
set CMD=echo Half a year elapsed
set /a SECS_IN_HALF_A_YEAR=365 / 2 * 24 * 60 * 60
loop_start:
ping -n %SECS_IN_HALF_A_YEAR% localhost > NUL
%CMD%
goto loop_start

I'm not saying it's pretty, but I thought it's a funky idea. Maybe some food for thought. :-)

Frerich Raabe
The first thing that comes to my head is, what about leap years? Additionally, you'd need to add this to machine startup, and somehow check the last runtime (what if there is a power outage?)
Dave
Thats a good point Dave.. to make it a bit more clearer .. it doesn't have to be 6 months EXACTLY.. but close enough :) So leap years is not a problem :) I'm an I.T Technician, and basically using vbs and batch script to schedule a friendly reminder for the client to come back for a tune-up every 6 months.. So between a basic popup message on there screen, and a friendly email reminder, its recurring revenue.
Greg
That idea would work Frerich .. I'll keep that in mind if no one has any better suggestions. Thanks for taking the time though :) I was also thinkin' bout the ping command .. but yeah.. its not the prettiest thing :)
Greg
Well whatever you do, don't leave a script like that running on a client's machine to schedule a friendly reminder :) I'd set up a reminder/scheduled email or similar in outlook and manually contact the customer, if it's for recurring revenue (easy money!) it's worth a personal touch surely?
Dave
Yeah.. thats the reason I'm against the ping idea :) It won't work if a shutdown occurs :) Because the time would stop. I'm more looking for a way to get the month 6 months from know, parse that into a variable, and use schtasks to schedule the task from the command line. And yeah, there will be emails going out; maybe even private messages on social network sites too.
Greg
A: 

you can download coreutils for windows . Then use date command like this

C:\test>gnu_date "+%Y%m%d" -d "6 months"
20110404

(it is renamed to gnu_date.exe )

I have not played with schtasks, but depending on what format of date it uses, you can change the parameters to suit schtasks

C:\test>gnu_date "+%Y-%m-%d" -d "6 months"
2011-04-04

If you need time as well

C:\test>gnu_date "+%Y-%m-%d-%H:%M:%S" -d "6 months"
2011-04-04-18:12:35

Use a for loop to save the date to a variable as desired. then pass it to schtasks for scheduling

ghostdog74
Thanks for taking the time to contribute user141527. That just gave me an idea .. :) Using the date command, a for loop; i should be able to get the month into a variable. Then using 'set /a' i should be able to add 6 (months) to the variable .. But if month variable is higher than 7 (months) how can i get it to stop @ 12 (December) and go back to 1 (January). From there I could use simple if statements to get the months name. And go from there :)
Greg
I was just tryin' diff ways with schtasks, using the '/sc monthly' and '/mo 6' parameters, but didn't work as I hoped unfortunately lol. That would of made things slightly easier :P
Greg
if you use the GNU date command (not the windows date command) as i have described, you won't need to do your own date calculation. The only thing you need to do is use the for loop to put the 6 months date into a variable, then find a way for schtasks to take in that variable.
ghostdog74
+2  A: 

Thanks to everyone who replied, and offered suggestions. I slept on it, woke up with the flu, and had a brainwave. Funny how things work out. I know this is overkill, and someone will come up with a better suggestion, but here goes anyway ..

REM Grab month number and put into variable
  FOR /F "TOKENS=1,2 eol=/ DELIMS=/ " %%A IN ('DATE/T') DO SET mm=%%B
REM Six months from now
  set /a addmm=%mm% + 6
  if %addmm% gtr 6 (set /a sixmonths=%addmm% - 12)
REM Determine month name
  if %sixmonths%==1 (set monthname=JAN)
  if %sixmonths%==2 (set monthname=FEB)
  if %sixmonths%==3 (set monthname=MAR)
  if %sixmonths%==4 (set monthname=APR)
  if %sixmonths%==5 (set monthname=MAY)
  if %sixmonths%==6 (set monthname=JUN)
  if %sixmonths%==7 (set monthname=JUL)
  if %sixmonths%==8 (set monthname=AUG)
  if %sixmonths%==9 (set monthname=SEP)
  if %sixmonths%==10 (set monthname=OCT)
  if %sixmonths%==11 (set monthname=NOV)
  if %sixmonths%==12 (set monthname=DEC)
REM Schedule Task  
  schtasks /create /TN TuneUpReminder /RU system /TR TuneUpReminder.bat /SC MONTHLY /M %monthname%
Greg
OK, I've hit a bit of a snag with this ..It all works well, but if those "6 months" go over the year, then the year will not be calculated into it ..So if I schedule it in August, it will schedule it from 6 months from now, but in the current year... For some reason it doesn't want to turn over into the new year when I run the schtasks command ..
Greg
+1  A: 

Since Greg's answer made me cry inside, here is some array like syntax:

for /F "tokens=%sixmonths%" %%A IN ("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC") DO set monthname=%%A

And since there’s always more than one way to skin a bat[ch]?

set /a sixmonths=%sixmonths% * 4
set months=666 JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
setlocal ENABLEDELAYEDEXPANSION
set monthname=!months:~%sixmonths%,3!
REM Optional: setlocal DISABLEDELAYEDEXPANSION
Anders
I knew there was a better way of doin' that part .. Thanks for that Anders .. xD
Greg