Here is the batch file rewritten to handle all error conditions right (hopefully as not fully tested).
@echo off
REM Backup files first and report any errors if not successful
%SystemRoot%\System32\xcopy.exe "C:\channels\filetransfer_process\*" "C:\channels\backup\" /C /Q /Y >"%TEMP%\%~n0.tmp"
REM Error checking
REM Note: The environment variable ERRORLEVEL contains the
REM return code of the last executed program or script.
if errorlevel 5 SET "BODY=File write error occurred" & GOTO MailError
if errorlevel 2 SET "BODY=Not enough memory or free space" & GOTO MailError
if not errorlevel 1 pause
set "FileCount=0"
for /F "usebackq" %%I in ("%TEMP%\%~n0.tmp") do set "FileCount=%%I"
if "FileCount" == "0" SET "BODY=No files were found to copy" & GOTO MailError
REM Temporary file with number of copied files as last line no longer needed.
del "%TEMP%\%~n0.tmp"
set "FileCount="
REM Before doing the network connection make sure Z drive is free for use
%SystemRoot%\System32\net.exe use Z: /delete 2>nul
REM Proceed with a network connection using Z with error checking.
%SystemRoot%\System32\net.exe use /persistent:no
%SystemRoot%\System32\net.exe use Z: \\dcqwdbs034\D$\arrivals password /user:domain\username
if errorlevel 1 SET "BODY=Net use connection failed" & GOTO MailError
if not exist Z:\ SET "BODY=Net use connection failed" & GOTO MailError
REM Move files to MSCM server.
move /Y "C:\channels\filetransfer_process\*" "Z:\"
if errorlevel 1 (
%SystemRoot%\System32\net.exe use Z: /delete
SET "BODY=File not found, could not be moved/renamed or bad parameters"
GOTO MailError
)
REM Remove network mapped Z drive.
%SystemRoot%\System32\net.exe use Z: /delete
%SystemRoot%\System32\net.exe use /persistent:yes
goto :EOF
REM Perform the error notification via BLAT.
:MailError
%SystemRoot%\System32\net.exe use /persistent:yes
del "%TEMP%\%~n0.tmp" 2>nul
"D:\Program Files\BLAT\blat.exe" -Install -Server mail1.sutterhealth.org -f name@domain.org -u name@domain.org -Pw mypasswd "D:\Program Files\BLAT\blat.exe" -To name@domain.org.org -Subject "File Transfer Error" -Body "%BODY%"
XCOPY is executed with option /Q
to suppress output of copied files. But XCOPY outputs nevertheless as final summary information the number of copied files. This output is redirected into a temporary file for later evaluation. But first is the exit code of XCOPY evaluated.
if errorlevel 2
means if exit code of command/application is greater or equal 2
and so if errorlevel 5
must be the first IF condition.
[
and ]
have no special meanings on a string comparison. They are just two literal characters. So don't add them on a string comparison. if NOT "%errorlevel%"=="0" pause
would be absolutely enough.
The double quotes have a special meaning for command interpreter as marking begin/end of an argument string in which the characters should be interpreted literally with exception of %
and !
on delayed expansion enabled. But please note that "
are always included by IF on comparing the two arguments. In other words if
does not remove surrounding double quotes before comparing the arguments.
ERRORLEVEL
has always an integer value assigned as string and therefore it is safe to use if NOT %ERRORLEVEL% == 0 pause
to make the string comparison a bit faster because of just two bytes have to be compared (ASCII representation of 0
and string terminating null byte, i.e. 0x30, 0x00) instead of four bytes (quote byte, ASCII representation of 0
, quote byte and string terminating null byte, i.e. 0x22, 0x30, 0x22, 0x00).
But best is using if not errorlevel 1
which means if exit code of previous command/application is lower than 1
. Nearly all applications exit with 0
on success and a positive number greater 0
on an error condition. Therefore if not errorlevel 1
working also within a command block is nearly always better than if %ERRORLEVEL% == 0
for testing on success.
The command FOR with option /F
as used in this batch file reads the lines from specified file line by line, skips empty lines, skips lines starting with a semicolon, splits up each line into substrings using default delimiters space and horizontal tab and assigns first space/tab delimited string to specified loop variable I
. In this case this should be always the number of copied files.
The application NET does often not exit with a value greater 0 on an error. So better verify if drive Z:
really exists after mapping network share to a drive letter. It is also better making the network drive mapping not persistent stored in Windows registry of current user. BTW: The domain, user name and password posted in code in question are hopefully fake data.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
goto /?
move /?
net /?
net use /?
pause /?
rem /?
set /?
xcopy /?
See also: