I've got a little script that will check for new files in a folder, and it will print all of the PDF files. Whenever the print fails, the %errorlevel% variable will go up to 1. I'm trying to use an if statement with goto and labels to get it to work but I can't figure out what is going on.
The script is:
:printfile
echo printing %1
set fname=%1
set fullFname="print\STW_Print\STW_Printer_TEST\%fname:~1%
echo ERLVL: %errorlevel%
"C:\Program Files (x86)\SumatraPDF\SumatraPDF.exe" -silent -print-to "\\s8011\OPS_2055_IS" %
echo ERLVL: %errorlevel%
set logFilename=%DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4%
if %errorlevel% neq 0 goto error
echo Moving %fname% to printed
move %fullFname% STW_printed
echo %time% %1 Printed on STWTEST and Moved>> Printlogs\TEST-%logFilename%-log.txt
goto eof
:error
echo Moving %fname% to failed
move %fullFname% STW_failed
echo %time% %1 Failed on STWTEST and Moved>> Printlogs\TEST-%logFilename%-log.txt
GOTO eof
:eof
The line that calls the script:
for /f "tokens=*" %%i in ('dir print\STW_Print\STW_Printer_TEST\*.pdf /b') do (call :printfile "%%i")
And my output:
printing "BADTEST (2) - Copy.pdf"
ERLVL: 0
ERLVL: 1
Moving "BADTEST (2) - Copy.pdf" to printed
1 file(s) moved.
printing "BADTEST (2).pdf"
ERLVL: 0
ERLVL: 1
Moving "BADTEST (2).pdf" to printed
1 file(s) moved.
printing "BADTEST (3) - Copy.pdf"
ERLVL: 0
ERLVL: 1
Moving "BADTEST (3) - Copy.pdf" to printed
1 file(s) moved.
I can't figure out why it's not moving to failed. Any help would be greatly appreciated!
It is because you check errorlevel after doing the SET command... which clears errorlevel. Move your 'set logfilename...' line farther up. Also, when using errolevel you can just do
if errorlevel 1 goto :error
Related
I have multimedia file viewing software that I call in a batch script to load files using an /LOADFILES argument. This argument accepts multiple files separated by semicolons ";".
What I would like is a menu from which I can select the files I want to open.
For example :
Sample_01
Sample_02
Sample_03
Sample_04
Sample_05
All
What is your choice ?
And what we have selected ends up stored in a variable which is interpreted by the /LOADFILES argument.
For now, my script is able to open all the existing samples one after the other :
#echo off
for /f "delims=" %%I in ('dir /a:d-h /b "%SystemDrive%\software\sample\*"') do (
"%SystemDrive%\software\Viewer.exe" /LOADFILES="%%I"
)
pause
exit
But I would like it to be able to read only the samples that I have selected from a menu, in separate instances of the program.
I have no specific idea of about how to achieve this.
Any help would greatly help me improve my script.
Thank you.
Here is a (very basic) script to show you the basic concept:
#echo off
setlocal
set "loadfiles="
:AddSamples
cls
echo current loadfiles: %loadfiles:~1%
echo add sample number
echo 1 - Sample_01
echo 2 - Sample_02
echo 3 - Sample_03
echo 4 - Sample_04
echo 5 - Sample_05
echo A - All and Go
echo G - Done and Go
choice /c 12345AG /m "What is your choice? "
if %errorlevel% == 1 set "loadfiles=%loadfiles%;Sample_01.mp3
if %errorlevel% == 2 set "loadfiles=%loadfiles%;Sample_02.mp3
if %errorlevel% == 3 set "loadfiles=%loadfiles%;Sample_03.mp3
if %errorlevel% == 4 set "loadfiles=%loadfiles%;Sample_04.mp3
if %errorlevel% == 5 set "loadfiles=%loadfiles%;Sample_05.mp3
if %errorlevel% == 6 set "loadfiles=;Sample_01.mp3;Sample_02.mp3;Sample_03.mp3;Sample_04.mp3;Sample_05.mp3" & goto :continue
if %errorlevel% == 7 goto :continue
goto :AddSamples
:Continue
set "loadfiles=%loadfiles:~1%"
"%SystemDrive%\software\Viewer.exe" /LOADFILES=%loadfiles%
I am using a Batch File to search a list of functions for an exact match, wondering if its possible to do a key word search, so right now i have to type "open cmd"
(variations on spacing and capital letters are accounted for)
Id like to switch it over to a system that can look for "cmd" and perform the action so "hey, open cmd please" would yield the same result as the old system
Old system:
setlocal
:: /STARTUP
set speech=start scripts\nircmd.exe speak text
cls
:begin
set TALK=TypeSomething
SET /P TALK=
set TALK=%TALK:?=%
call :%TALK: =% 2>NUL
if %errorlevel% equ 0 goto begin
exit /B 0
:unknown
echo Old function no longer supported
:opencmd
:BOSopencmd
:cmd
echo Command Prompt has now been opened in a new window, sir.
%speech% "Command Prompt has now been opened in a new window, sir."
start scripts\cmd.bat
exit /B 0
It is based of a chat bot i tried to make in middle school so the %speech% is not an important item, i can add that and the echo later. I just need a system that works like the old one if possible. The other i can have any number of functions with
:cmd
start cmd
Exit /B 0
or
:reddit
start http://www.reddit.com/
exit /B 0
at these need to be able to stack. I can transition to having scripts for each function in a separate batch files if needed. Ive tried trying findstr but it wasn't giving the desired results. Ive exhausted my knowledge on what i might be able to do but I've come up short lol, If you are having trouble understanding what i'm asking don't hesitate to let me know
I learn by taking things apart so partial code is appreciated but will not be much help until after I've figured out what does what .
Here's a sample of how you might approach it using ECHO, FINDSTR, and CALL (This is a modified example from the original per your request to be able to process multiple keywords):
#echo off
set TST_FNDFLG=FALSE
set TST_USRANS=
set /P TST_USRANS=Enter keywords:
if "%TST_USRANS%" == "" goto ENDIT
echo %TST_USRANS% | findstr /i "CMD" >NUL 2>&1
if ERRORLEVEL 1 goto TRYRED
call :DOCMD
:TRYRED
echo %TST_USRANS% | findstr /i "REDDIT" >NUL 2>&1
if ERRORLEVEL 1 goto TRYGOO
call :DORED
:TRYGOO
echo %TST_USRANS% | findstr /i "GOOGLE" >NUL 2>&1
if ERRORLEVEL 1 goto TRYEND
call :DOGOO
goto TRYEND
:DOCMD
if [%TST_FNDFLG%] == [FALSE] echo.
echo CMD was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DORED
if [%TST_FNDFLG%] == [FALSE] echo.
echo REDDIT was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DOGOO
if [%TST_FNDFLG%] == [FALSE] echo.
echo GOOGLE was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:TRYEND
echo.
if [%TST_FNDFLG%] == [TRUE] echo No more keywords found
if [%TST_FNDFLG%] == [FALSE] echo Did not find any known keywords
goto ENDIT
:ENDIT
echo.
set TST_USRANS=
set TST_FNDFLG=
I am trying to write the below code, and I want it to display the error before it exits, but whenever I run it, it exits right away.
#echo off
cd "haha"
if %errorlevel% 1 (
echo Failure reason given is %errorlevel%
sleep 5
exit /b %errorlevel%
)
echo files deleted successfully!
del /Q *
pause
I have also tried timeout /t 5 doesn't seem to work.
This should work :
#echo off
cd "haha" 2>nul
if %errorlevel%==1 (
echo Failure reason given is %errorlevel%
timeout /t 5
exit /b %errorlevel%
)
The correct syntax is
if errorlevel 1 (
meaning if errorlevel is 1 or greater
OR
if %errorlevel% geq 1 (
which means the same thing.
As it stands, cmd is interpreting you code as
if 1 1 (
(assuming errorlevel is 1). This is a syntax error, so cmd shows a message. If you are running by point-click and giggle, the window will close. If you are running from the prompt, then cmd will report a syntax error.
Be warned however that executing an exit statement from the prompt will abort the cmd instance. Better to use goto :eof unless you have good reason otherwise.
timeout /t 5 should work, but will generate a countdown.
timeout /t 5 >nul should appear simply to wait. The issue is that you have to solve the if syntax first, else the timeout instruction won't be reached.
I was wondering if anyone could help me with a very simple rework of this script I inherited. I have no previous experience with batch files and needed to modify this already working script in a very simple manner.
Currently, this script does the following:
- Monitors a folder and looks to see if there are files in it
- If there are, it executes a FTP transfer via command line
- Then, it moves the files into a archive folder created and named with the current timestamp and writes something to a text log file
- If there are no files, the script exits and does nothing.
As of now, the script is looking for, processing, and moving all the files at once. I was looking to see if I could be pointed int the right direction with help on how to modify the script so that it does each file one by one, instead of using . everywhere. Ultimately, I think all I need to do is figure out how to do the loop correctly and read/store the filenames to use as variables instead of using . Any help would be appreciated.
#ECHO OFF
:: Set count of files = 0
SET X=0
:: Set timestamp for processed folders
set TIMESTAMP=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%-%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%.%TIME:~9,2%
:: If more than 0 files exist begin ftp and file archival otherwise exit
FOR %%i IN (c:\Encoded_HL7_Vanderbilt\*.*) DO IF EXIST %%i (SET X=1)
IF [%X%] gtr [0] (cd\..\..
cd\"Program Files (x86)\Ipswitch\WS_FTP 12"
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error switching to ftp program directory>E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt
exit)
wsftppro -s local:C:\Encoded_HL7_Vanderbilt\*.* -d Vandy!Vanderbilt:/incoming/
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error transmitting file to ftp server>E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt
exit)
md "E:\Processed_HL7_Vanderbilt\%1\%TIMESTAMP%"
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error creating archive directory>E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt
exit)
move "C:\Encoded_HL7_Vanderbilt\*.*" "E:\Processed_HL7_Vanderbilt%1\%TIMESTAMP%"
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error moving files to archive directory>E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt
exit)) ELSE (exit)
echo %TIMESTAMP% File transfer completed successfully>E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.success.txt
exit
Give this a walk around the park: if any file generates an error then it will stop processing further files.
#ECHO OFF
set "folder=%~1"
:: Set timestamp for processed folders
set TIMESTAMP=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%-%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%.%TIME:~9,2%
:: If more than 0 files exist begin ftp and file archival otherwise exit
FOR %%a IN (c:\Encoded_HL7_Vanderbilt\*.*) DO (
cd\"Program Files (x86)\Ipswitch\WS_FTP 12"
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error switching to ftp program directory>E:\HL7_Vanderbilt_log\%folder%\%TIMESTAMP%.error.txt
goto :done)
wsftppro -s local:%%a -d Vandy!Vanderbilt:/incoming/
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error transmitting "%%a" file to ftp server>E:\HL7_Vanderbilt_log\%folder%\%TIMESTAMP%.error.txt
goto :done)
md "E:\Processed_HL7_Vanderbilt\%folder%\%TIMESTAMP%" 2>nul
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error creating archive directory>E:\HL7_Vanderbilt_log\%folder%\%TIMESTAMP%.error.txt
goto :done)
move "%%a" "E:\Processed_HL7_Vanderbilt\%folder%\%TIMESTAMP%"
IF ERRORLEVEL 1 (echo %TIMESTAMP% Error moving "%%a" file to archive directory>E:\HL7_Vanderbilt_log\%folder%\%TIMESTAMP%.error.txt
goto :done)
)
echo %TIMESTAMP% File transfers completed successfully or no files were found>E:\HL7_Vanderbilt_log\%folder%\%TIMESTAMP%.success.txt
exit
:done
goto :EOF
try this, it might work for you:
#ECHO OFF &SETLOCAL
:: Set count of files = 0
SET /a count=0
:: Set timestamp for processed folders
set "TIMESTAMP=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%-%TIME:~0,2%.%TIME:~3,2%.%TIME:~6,2%.%TIME:~9,2%"
cd "%ProgramFiles(x86)%\Ipswitch\WS_FTP 12" || (
echo %TIMESTAMP% Error switching to ftp program directory>"E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt"
exit /b 1
)
md "E:\Processed_HL7_Vanderbilt\%1\%TIMESTAMP%" || (
echo %TIMESTAMP% Error creating archive directory>"E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt"
exit /b 1
)
:: If more than 0 files exist begin ftp and file archival otherwise exit
FOR %%i IN (c:\Encoded_HL7_Vanderbilt\*) DO (
set /a count+=1
REM I don't know the wsftppro command line parameters, pls. check the man page
wsftppro -s local:"%%~i" -d Vandy!Vanderbilt:/incoming/ || (
echo %TIMESTAMP% Error transmitting file to ftp server>"E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt"
exit /b 1
)
move "%%~i" "E:\Processed_HL7_Vanderbilt\%1\%TIMESTAMP%" || (
echo %TIMESTAMP% Error moving files to archive directory>"E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.error.txt"
exit /b 1
)
)
if %count% equ 0 (
rd "E:\Processed_HL7_Vanderbilt\%1\%TIMESTAMP%" 2>nul
exit /b 1
)
echo %TIMESTAMP% File transfer completed successfully>"E:\HL7_Vanderbilt_log\%1\%TIMESTAMP%.success.txt"
I have a build step in my build configuration thats runner type "Command Line", running a custom script.
The script is executing Robocopy:
robocopy "%teamcity.build.workingDir%\Code" "\\target\d$\Web\Target Sites" /E /NP /LOG:robocopy.log
if ERRORLEVEL GEQ 4 (
"D:\blat.exe" "robocopy.log" -to me#me.com -f me#me.com -subject "Error during robocopy on TEAMCITY" -server mail.me.com
)
exit /B 0
The Robocopy command is working fine but I keep getting an email and in the build log I keep seeing:
GEQ was unexpected at this time.
The ERRORLEVEL check isn't working for some reason?
I tried IF %ERRORLEVEL% GEQ but this breaks my build has TeamCity expects me to pass a build parameter.
Does this only work as an "Executable with parameters"?
Neil, you might try escaping the percent sign.
Try IF %%ERRORLEVEL%% GEQ ...
I've just run into this problem, and appreciate #John's answer.
Here is what I came up with:
robocopy [from] [to] /MIR
REM http://ss64.com/nt/robocopy-exit.html
IF %%ERRORLEVEL%% EQU 0 (
ECHO No errors occurred, and no copying was done; The source and destination directory trees are completely synchronized.
EXIT 0
)
IF %%ERRORLEVEL%% EQU 1 (
ECHO One or more files were copied successfully, new files have arrived.
EXIT 0
)
IF %%ERRORLEVEL%% EQU 2 (
ECHO Some Extra files or directories were detected. No files were copied.
EXIT 0
)
IF %%ERRORLEVEL%% GEQ 3 (
ECHO Robocopy Exit Codes: http://ss64.com/nt/robocopy-exit.html
EXIT %%ERRORLEVEL%%
)