When was the last time you created a Windows batch file?

If the last time you wrote a Windows Batch file was back in the good ol’ MS-DOS or Windows 95 days, then time has come to step up and experience that Windows Command files is the new black 🙂

Today Windows Command files has grown into an advanced script language having many interesting features. The tool iInstall.Cmd uses many of the new features in order to install a Savefile on your iSeries.

Did you know that a Windows Command script can:

  • Have the user enter information?
  • Convert data?
  • Execute subroutines?
  • Do simple arithmetic?
  • Do advanced functionality by calling build-in Windows programs?

I am working with software development on IBM’s iSeries (AS/400, IBMi, …), and that is why we are going to take a look at a Windows Command file, that transfers a library from the iSeries to the PC. The Command file is called SAVLIB.CMD, as it’s functionality is similar to the iSeries command SAVLIB (Save Library). The SAVLIB command gets executed on the iSeries when the Command file runs. In short, the SAVLIB.CMD Command file is using the Windows FTP client to do all ‘the hard work’ on the iSeries, avoiding having you to type a lot of FTP commands.

You can download the SAVLIB.CMD here.

The first few statements I am using in the Command file, is used to build the name of three workfiles. One to contain the FTP script that must be executed and to log files. One of the logfiles is used to collect status information in case something fails and the other one is used to hold various information.

set scriptfile="%~dp0%~n0.script"
set logfile="%~dp0%~n0.log"
set logfile2="%~dp0%~n02.log"

The command ‘%~dp0%~n0’ is actually two. ‘%~dp0’ returns the drive and path for parameter 0 (zero), which is actually where the Command file is stored. ‘%~n0’ returns the Command file’s name. I am using these two expressions as I want to have a file with the same name as the SAVLIB Command file and it must be located together with the SAVLIB Command file. It is the same for the two log files.

The next new thing is the use of parenthesis, ‘else’ and the switch ‘/p’ with the ‘set’ statement:

REM
REM If parameter is missing, ask for it.
REM
If "%3" == "" (
  Echo.
  set /p iseriesname= Enter DNS-name or IP of iSeries:
  ) Else (
  set iseriesname=%3
  )

Using the switch ‘/p’ after the ‘set’ statement means, that the user is to type some information (to be prompted). The text written after the equal sign, is the text that must be shown to the user as caption. ‘/p’ is the options that we have been waiting for, ever since the batch file was invented, and finally it is here.

Please note, the statements that is conditioned are written between parenthesis and the possibility to use ‘Else’.

Multiple times in the SAVLIB Command file, I am creating a script to be executed by the FTP client:

REM
REM Create FTP script to be executed on the iSeries.
REM
Echo open %iseriesname% > %scriptfile%
Echo %user% >> %scriptfile%
Echo %pwd% >> %scriptfile%
Echo quote system >> %scriptfile%
Echo Quit >> %scriptfile%

The option to redirect output to a file have always been possible. Please note, in the first line I am using just one ‘>’ and in the other lines there are two ‘>>’. One ‘>’ means that the file to receive the output must be (re-) created. ‘>>’ means adding to the existing file.

When the FTP script has been created, it must be executed:

REM
REM Execute FTP
REM
FTP -s:%scriptfile% > %logfile2% 2>&1

The various parameters on the command line indicated that the file ‘%scriptfile%’ contains the script to be run. ‘> %logfile2% 2>&1’ means that the output from the FTP client must be written to the log file ‘%logfile2%’. ‘2>&1’ means that ‘Standard out’ as well as ‘Error out’ must be written to the log file. If you do not state this, only the output from FTP commands that succeeds will get written to the log file and those that gives errors will be written to the screen.

When the FTP client terminates, the log file will be searched for errors:

FIND "530 " < "%logfile2%" > nul
If not errorlevel == 1 (
Echo.
Call :ErrHdr
Call :ErrDetLin "User id/password is not correct on target system."
Call :ErrFtr
Call :ErrFTPLog
Pause
Goto Exit
)

I am looking for error code ‘530’. That error code means that the userprofile or the password is not correct. To check the log file for the error code, I am calling a Windows program called FIND.  FIND is capable of reading a file and search for an argument. If FIND finds the argument, it will set the ERRORLEVEL to 1. I test for this value and then calls a number of subroutines that will printout error messages on the screen and write to the log file.

Subroutines are one of the newer things in Command files. En important thing to do when you want to return from a subroutine, is that you must end it with the statement ‘Exit /b’:

REM
REM Write Error detail line
REM on screen and in file.
REM -----------------------
:ErrDetLin Str
if "%~1" == "" Echo.
if not "%~1" == "" Echo %~1

if "%~1" == "" Echo. >> "%logfile%"
if not "%~1" == "" Echo %~1 >> "%logfile%"
Exit /b

If you leave out the switch ‘/b’ then the Command file will end.

You have now seen some of the new things that has been added to Windows Command files since the good ol’ MS-DOS and Windows 95 days. As you have seen, you can make quite functional and advanced Windows Command files. You can download SAVLIB.CMD, and take a look at it, as there are more of the new things to look at. You could use it for it’s purpose, transfer a library in a savefile, easily and simple 🙂

Useful links: