Hello all,
I'm looking for a way to have a 'countdown timer' as such to run outside of the Main Macro loop in an IF statement. A Fail safe.
If> time has surpassed, exit the macro, else keep going.
This is because the macro itself may run for 10 to 30 minutes.
Once 30 minutes may have surpassed maybe due to an error, maybe there was nothing left for it to do i'd like it to be able to reset itself.
If it's too difficult, I may end up just doing a self=self+1 in the last loop where it may get stuck forever.
Thanks for any help you can provide!
Ways to tell if time has surpassed?
Moderators: Dorian (MJT support), JRL
-
- Automation Wizard
- Posts: 1101
- Joined: Fri Jan 07, 2005 5:55 pm
- Location: Somewhere else on the planet
Are you compiling the macro and running the .exe? If so when the compiled macro, e.g. macro1.exe, starts it can also start macro2.exe with RunProgram>. macro2.exe will wait for a defined time, then check for the macro1.exe process and if it still exists kill it.
Here's an example for macro2.exe.
I can't think of a way to do the same thing with uncompiled scripts running under macroscheduler.
Here's an example for macro2.exe.
Code: Select all
Let>APP_TITLE=Macro2
VBSTART
'Kills a process given its process name
Sub killProcess(pgm)
set wmi = getobject("winmgmts:")
sQuery = "select * from win32_process " & "where name='" & pgm & "'"
set processes = wmi.execquery(sQuery)
for each process in processes
process.terminate
next
End Sub
'returns the number of copies of ProcessName that are running
'will return 0 if ProcessName is not running
Function IsProcessRunning(ProcessName)
Set oWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcessList = oWMIService.ExecQuery ("Select Name from Win32_Process where Name='" & ProcessName & "'")
IsProcessRunning = colProcessList.count
End Function
VBEND
//set the wait time
Wait>300
Label>begin
//check if process is still running
VBEval>IsProcessRunning("macro1.exe"),maccheck
If>maccheck=0,finish
If>maccheck>0,killit
Label>killit
VBRun>Killprocess,macro1.exe
Label>finish
Yeah it's not a executable macro.
I tired doing it via getting the current hour and minutes then passing those values onto a holder. (Let command)
Then every time the lower loop (the one that can run forever) goes through it's 30 second cycle it gets a new current hour and minutes and checks to see if they are half an hour from the first place holder.
My issue in getting this to work was that I'd be working in 60 instead of infinite.
Thanks for your reply Me_again.
I tired doing it via getting the current hour and minutes then passing those values onto a holder. (Let command)
Then every time the lower loop (the one that can run forever) goes through it's 30 second cycle it gets a new current hour and minutes and checks to see if they are half an hour from the first place holder.
My issue in getting this to work was that I'd be working in 60 instead of infinite.
Thanks for your reply Me_again.
I started this earlier and just got back to it. Now that there has been some conversation, I'm not sure if it applies but...
The following sample script writes macro 2 which is a timer. I'm sure that part will work for you as an infinite timer. If your macro 1 has actually stalled, then my method as described here will not work.
Macro 2 times using VBScript timer. The VBScript timer reports the number of seconds since your computer started so its kind of like a personal Julian time. Its a perpetually upward incrementing number.
When the script times out a file is created and macro 2 shuts down. Macro 1 checks for the existence of the file each time it loops. When the file eventually exists, Macro 1 shuts down. I've used this method several times but not for shutting down a locked script. Macro 1 needs to be looping even if its not accomplishing anything.
I think that you could close a dead process using DOS taskkill in a batch file. It would be shutting down Macro Scheduler so what you'd want is for the timer script to write then run a batch file that would terminate the msched.exe process(s), pause for a couple of seconds then restart msched.exe. When msched.exe is closed both scripts would be shut down.
If the process is not "stalled", for example waiting for a window to open that is never going to open, the following script might work.
Sorry if this was rambling.
Dick
The following sample script writes macro 2 which is a timer. I'm sure that part will work for you as an infinite timer. If your macro 1 has actually stalled, then my method as described here will not work.
Macro 2 times using VBScript timer. The VBScript timer reports the number of seconds since your computer started so its kind of like a personal Julian time. Its a perpetually upward incrementing number.
When the script times out a file is created and macro 2 shuts down. Macro 1 checks for the existence of the file each time it loops. When the file eventually exists, Macro 1 shuts down. I've used this method several times but not for shutting down a locked script. Macro 1 needs to be looping even if its not accomplishing anything.
I think that you could close a dead process using DOS taskkill in a batch file. It would be shutting down Macro Scheduler so what you'd want is for the timer script to write then run a batch file that would terminate the msched.exe process(s), pause for a couple of seconds then restart msched.exe. When msched.exe is closed both scripts would be shut down.
If the process is not "stalled", for example waiting for a window to open that is never going to open, the following script might work.
Code: Select all
IfFileExists>%TEMP_DIR%~Timer~.scp
DeleteFile>%TEMP_DIR%~Timer~.scp
EndIF
//3600=1 hour
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Let>TotalTime=10
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,IfFileExists>%TEMP_DIR%~EndOfTime~.tmp
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, DeleteFile>%TEMP_DIR%~EndOfTime~.tmp
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,EndIF
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBSTART
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBEND
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBEval>timer,StartTime
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Label>Loop
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, VBEval>timer,EndTime
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, If>{(%EndTime%-%StartTime%)>%TotalTime%}
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Writeln>%TEMP_DIR%~EndOfTime~.tmp,wresult,%TotalTime%
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Goto>EOF
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, EndIf
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Wait>0.01
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Let>ElapsedTime={(%EndTime%-%StartTime%)}
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Message>Elapsed time = %ElapsedTime%%TAB% seconds
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Goto>Loop
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Label>EOF
Let>RP_WAIT=0
Run>%COMMAND_LINE% %TEMP_DIR%~Timer~.scp
Label>Loop
Wait>0.01
IfFileExists>%TEMP_DIR%~EndOfTime~.tmp
Goto>EOF
EndIf
Goto>Loop
Label>EOF
Dick
Here's the same thing to kill a "stalled" script.
Code: Select all
IfFileExists>%TEMP_DIR%~Timer~.scp
DeleteFile>%TEMP_DIR%~Timer~.scp
EndIF
IfFileExists>%TEMP_DIR%killmsched.bat
DeleteFile>%TEMP_DIR%killmsched.bat
EndIF
//3600=1 hour
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Let>TotalTime=10
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,IfFileExists>%TEMP_DIR%~EndOfTime~.tmp
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, DeleteFile>%TEMP_DIR%~EndOfTime~.tmp
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,EndIF
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBSTART
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBEND
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,VBEval>timer,StartTime
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Label>Loop
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, VBEval>timer,EndTime
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, If>{(%EndTime%-%StartTime%)>%TotalTime%}
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, //Writeln>%TEMP_DIR%~EndOfTime~.tmp,wresult,%TotalTime%
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,taskkill /im msched.exe
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,If errorlevel 0 goto killed
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,echo Process not terminated
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,pause
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,goto end
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,:killed
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,start "%COMMAND_LINE%"
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, WriteLn>%TEMP_DIR%killmsched.bat,wresult,:end
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Let>RP_WAIT=0
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Run>cmd /c %TEMP_DIR%killmsched.bat
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Goto>EOF
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, EndIf
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Wait>0.01
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Let>ElapsedTime={(%EndTime%-%StartTime%)}
WriteLn>%TEMP_DIR%~Timer~.scp,wresult, Message>Elapsed time = %ElapsedTime%%TAB% seconds
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Goto>Loop
WriteLn>%TEMP_DIR%~Timer~.scp,wresult,Label>EOF
Let>RP_WAIT=0
Run>%COMMAND_LINE% %TEMP_DIR%~Timer~.scp
Label>Loop
Wait>0.01
IfFileExists>%TEMP_DIR%~EndOfTime~.tmp
Goto>EOF
EndIf
Goto>Loop
Label>EOF
- Marcus Tettmar
- Site Admin
- Posts: 7395
- Joined: Thu Sep 19, 2002 3:00 pm
- Location: Dorset, UK
- Contact:
To measure elapsed time I always use VBScript's Timer function. Timer returns seconds since midnight. So if you have a loop use Timer before and then Timer within and take one from t'other and you have elapsed time. This method is explained here: http://www.mjtnet.com/loadtesting.pdf
Marcus Tettmar
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?
http://mjtnet.com/blog/ | http://twitter.com/marcustettmar
Did you know we are now offering affordable monthly subscriptions for Macro Scheduler Standard?