altquark
asked on
CMD Script on Windows causes Batch Recursion error and aborts
Hi Guys
I've created a script that emails users when a file in a directory is more than 20 minutes old. The script works really well, but after running for about 24 hours or so, it errors out with the following error :
The script looks at the spool directory on the local windows machine, and compares the creation date of the file against the system time. If there is no file that is older than 20 minutes, then the script sleeps for 1 minute. If there is a file older than 20 minutes, the script uses the vbscript to pull information about the print queue, and uses a program called "gbmail" to send an email to a distribution list (contained in emails.txt) with the output from the vbscript and then sleeps for 5 minutes before going back to the top of the script.
The following is the script (I modified slightly it to remove security information)
I'd really appreciate it if someone could point me to a solution to prevent the recursion from happening. Thankyou in advance !
I've created a script that emails users when a file in a directory is more than 20 minutes old. The script works really well, but after running for about 24 hours or so, it errors out with the following error :
****** B A T C H R E C U R S I O N exceeds STACK limits ******and I have to restart the script again.
Recursion Count=428, Stack Usage=90 percent
****** B A T C H PROCESSING IS A B O R T E D ******
The script looks at the spool directory on the local windows machine, and compares the creation date of the file against the system time. If there is no file that is older than 20 minutes, then the script sleeps for 1 minute. If there is a file older than 20 minutes, the script uses the vbscript to pull information about the print queue, and uses a program called "gbmail" to send an email to a distribution list (contained in emails.txt) with the output from the vbscript and then sleeps for 5 minutes before going back to the top of the script.
The following is the script (I modified slightly it to remove security information)
@echo off
:: Wmic removes regional differences - it has problems with commas in filenames.
:top
@echo iteration
setlocal
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "stamp=%YYYY% %MM% %DD% %HH% %Min%"
call :DateToMinutes %stamp% NowMins
for /f "delims=" %%a in ('dir C:\Windows\System32\spool\PRINTERS\*.SPL /a-d /b') do call :CheckMins "%%a"
goto :Restart
:CheckMins
::echo checkmins
set "filestamp="
set "filemins="
set "MinsOld="
set "YY=" & set "YYYY=" & set "MM=" & set "DD="
set "HH=" & set "Min=" & set "Sec=" & set "dt="
set "file=%~1"
set "filea=%file:\=\\%"
WMIC DATAFILE WHERE name="C:\\Windows\\System32\\spool\\PRINTERS\\%file%" get lastmodified | find "." >file.tmp
for /f %%a in (file.tmp) do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "filestamp=%YYYY% %MM% %DD% %HH% %Min%"
::echo %filestamp%
del file.tmp 2>nul
if not defined yyyy goto :EOF
call :DateToMinutes %filestamp% FileMins
set /a MinsOld=%NowMins%-%FileMins%
::echo Now:%NowMins% File:%FileMins% Fileage:%minsold% "%~1"
if %MinsOld% gtr 20 goto DoThis
goto :Restart
:DateToMinutes
setlocal
set yy=%1&set mm=%2&set dd=%3&set hh=%4&set nn=%5
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)
set /a dd=100%dd%%%100,mm=100%mm%%%100
set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
set /a j=j/5+dd+y*365+y/4-y/100+y/400-2472633
if 1%hh% LSS 20 set hh=0%hh%
if /i {%nn:~2,1%} EQU {p} if "%hh%" NEQ "12" set hh=1%hh%&set/a hh-=88
if /i {%nn:~2,1%} EQU {a} if "%hh%" EQU "12" set hh=00
if /i {%nn:~2,1%} GEQ {a} set nn=%nn:~0,2%
set /a hh=100%hh%%%100,nn=100%nn%%%100,j=j*1440+hh*60+nn
endlocal&set %6=%j%&goto :EOF
:DoThis
::echo oldfile "%file%"
::c:\batch\sysinternals\handle %file%
for /f "tokens=1,2,3,4* delims=. " %%a in ("%file%") do set spoolno=%%a
set spoolno=%spoolno:0=%
cscript C:\Windows\System32\Printing_Admin_Scripts\en-US\prnjobs.vbs -l -j %spoolno% >c:\batch\spoolfile.txt
for /f "tokens=*" %%a in (emails.txt) do C:\batch\gbmail.exe -to %%a -h smtp.host.com -from sender@host.com -s "%file% has been in the system for %MinsOld% minutes on %COMPUTERNAME%" -file spoolfile.txt >nul
::After emailing - sleep for 5 minutes
c:\batch\sleep 300
:Restart
c:\batch\sleep 60
Goto :top
I'd really appreciate it if someone could point me to a solution to prevent the recursion from happening. Thankyou in advance !
Looking a little further, my initial thought would be that you are not returning from the "call :CheckMins" inside a FOR loop. Rather you use GOTO statements during that call to restart the script at the top, and enter the FOR loop again. This likely leaves the prior FOR loop waiting for the "call :CheckMins" toi return, which it never does. Over time these pile up until it aborts.
I'll look at what the code is doing a little more and try to make a recommendation to correct.
~bp
I'll look at what the code is doing a little more and try to make a recommendation to correct.
~bp
ASKER
Hi bill - the file name can be anything. Currently it's called "testit.bat" !
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Bill
The main issue has definitely gone - but now I'm getting a "Maximum setlocal recursion level reached." message. This happens every minute now. This doesn't seem to stop the batch program from running - so I'm in a lot better position. However, its still annoying - can you shed some light onto this new error ?
Jon
The main issue has definitely gone - but now I'm getting a "Maximum setlocal recursion level reached." message. This happens every minute now. This doesn't seem to stop the batch program from running - so I'm in a lot better position. However, its still annoying - can you shed some light onto this new error ?
Jon
Try moving line 7 above line 4.
~bp
~bp
ASKER
ok - Modified and testing....I'll let you know how it goes !
ASKER
It looks good after 7 hours. So, I'm going to accept your script as a solution ! Thankyou !
ASKER
Move line 7 (setlocal) to line 4 (before the :top) and it works great ! Thankyou !
Excellent, thanks for the feedback, glad that was helpful.
~bp
~bp
~bp