The best way to get started is making the simplest possible example.
Let's build and test one script function for addition and one for
subtraction. The arguments are passed by reference.
are, in fact, superfluous. They are permissible, though, and make for
a better documentation.
How does one return the values of more than one variable from a
subroutine? See the
module
below. For another example see the
A much more complicated, modular true-life script built might
serve as an example of subroutines in scripting. What this script
actually does is besides the point. The point in this connection is
its structure. Nevertheless, you might find
@echo off & setlocal enableextensions
:: Assign a value for the temporary folder variable temp_
call :AssignTemp temp_
:: Create a four-digit random string
call :Rand4 rand_
:: Do not allow running simultaneous instances of the script
call :CheckLock locked_
if defined locked_ (
if not defined cmdbox if defined PauseIfFromDesktop pause
goto :EOF)
:: Is help asked for
if "%~1"=="" (call :programTitle & echo. & call :ProgramHelp & goto _out)
if "%~1"=="?" (call :programTitle & echo. & call :ProgramHelp & goto _out)
if "%~1"=="/?" (call :programTitle & echo. & call :ProgramHelp & goto _out)
:: The location of the PGP program on the PC
:: pgp263i.zip
Pretty Good Privacy RSA public key cryptography
call :Is64bit is64bit_
if defined is64bit_ goto _out
set pgpProg_=C:\_F\PGP\PGP.EXE
if "%USERNAME%"=="qt" set pgpProg_=C:\_L\QT\PGP\PGP.EXE
if not exist "%pgpProg_%" (call :NotFound "%pgpProg_%" & goto _out)
:: Define the file to be decrypted and listed
:: The module takes %~1 and it returns filename_ and filefold_
call :AssignSource %~1 filename_ filefold_
:: Check for the existence of the file to be decrypted
if not exist "%filename_%" (call :NotFound "%filename_%" & goto _out)
:: Check for wildcards, do not allow
call :IsWild "%filename_%" wild_
if defined wild_ goto _out
:: Capture the foldername of the files' location
if not defined filefold_ set filefold_=%~dp1
:: Store the screen with PUSHSCR.EXE from
tsutld25.zip
c:\_f\tuki\pushscr %temp_%\lpgp%rand_%.scn /o
:: Decrypt and list the file with PGP
call :DecryptAndListFile "%filename_%"
:: Restore the screen with POPSCR.EXE from tsutld25.zip
c:\_f\tuki\popscr %temp_%\lpgp%rand_%.scn
if exist "%temp_%\lpgp%rand_%.scn" del "%temp_%\lpgp%rand_%.scn" > nul
:: Some concuding maitenance
call :CleanUp
:_out
:: Release the lockfile. Pause if from GUI as per
tscmd002.html.
for %%f in ("%temp_%\typepgpLockfile.tmp") do if exist %%f del %%f
if not defined cmdbox if defined PauseIfFromDesktop pause
endlocal & goto :EOF
rem Start of the subroutine modules
:programTitle
echo +-----------------------------------------------------------+
echo ^| TYPEPGP.CMD Type an encrypted file, wildcards not allowed ^|
echo ^| Prof. Timo Salmi, Last modified Wed 1-Aug-2018 ^|
echo +-----------------------------------------------------------+
goto :EOF
:AssignTemp
setlocal
set return_=%temp%
if defined mytemp if exist "%mytemp%\" set return_=%mytemp%
endlocal & set "%1=%return_%" & goto :EOF
:Rand4
setlocal
set /a rand4_=%random% %% 10000
set rand4_=0000%rand4_%
set rand4_=%rand4_:~-4%
endlocal & set "%1=%rand4_%" & goto :EOF
:AssignSource
setlocal
set filename_=%~1
set filefold_=
if "%~1"=="/1" (
set filename_=C:\_F\MYFOLD\MYLIST\PRIVATE.PGP
set filefold_=C:\_F\MYFOLD\MYLIST\)
if "%~1"=="/2" (
set filename_=C:\_F\MYFOLD\MYLIST\QTLIST.PGP
set filefold_=C:\_F\MYFOLD\MYLIST\)
if "%~1"=="/3" (
set filename_=C:\_F\MYFOLD\MYLIST\LOCALADM.PGP
set filefold_=C:\_F\MYFOLD\MYLIST\)
if "%~1"=="/4" (
set filename_=C:\_D\MAIL\MYREGIS.PGP
set filefold_=C:\_D\MAIL\)
if not defined filefold_ set filefold_=%~dp1
endlocal &
set "%2=%filename_%" &
set "%3=%filefold_%" & goto :EOF
:NotFound
call :programTitle
echo.
echo %1|findstr /c:"/">nul
if %errorlevel% EQU 0 (echo %1 No such switch&echo.&call :programHelp)
if %errorlevel% GTR 0 (echo %~1 not found)
goto :EOF
:IsWild
set return_=
echo %filename_%|findstr "[*?]">nul
if %errorlevel% GTR 0 goto _endIsWild
call :programTitle
echo.
echo Wildcards are not allowed in the file name
set return_=true
:_endIsWild
endlocal & set "%2=%return_%" & goto :EOF
:DecryptAndListFile
setlocal
set bn_=%~sn1
set ext_=%~x1
set fullname_=%filefold_%%~snx1
if /i not "%ext_%"==".pgp" (
call :programTitle
echo.
echo "%fullname_%" does not have a .PGP extension
goto _endDecryptAndListFile)
set path_=%path%
set tz_=%TZ%
set TZ=Europe/Helsinki
SET PGPPATH=C:\_F\PGP
if "%USERNAME%"=="qt" SET PGPPATH=C:\_L\QT\PGP
SET PATH=%PGPPATH%;%PATH%
@echo on
%PGPPATH%\pgp -m "%fullname_%"
@echo off
set path=%path_%
set path_=
set TZ=%tz_%
:_endDecryptAndListFile
goto :EOF
:Is64bit
setlocal
set return_=
if defined ProgramW6432 (
echo/
echo Exiting: %~f0 is incompatible with 64-bit Windows
set return_=true)
endlocal & set "%1=%return_%" & goto :EOF
:CleanUp
if /i not "%USERNAME%"=="me" goto _endCleanUp
if exist "C:\WINDOWS\Temp\PRIVATE.$??" del /p "C:\WINDOWS\Temp\PRIVATE.$??"
if exist "C:\WINDOWS\Temp\QTLIST.$??" del /p "C:\WINDOWS\Temp\QTLIST.$??"
if exist "C:\WINDOWS\Temp\LOCALADM.$??" del /p "C:\WINDOWS\Temp\LOCALADM.$??"
if exist "C:\WINDOWS\Temp\MYREGIS.$??" del /p "C:\WINDOWS\Temp\MYREGIS.$??"
:_endCleanUp
goto :EOF
:CheckLock
setlocal
if exist "%temp_%\typepgpLockfile.tmp" (
call :programTitle
echo.
echo An instance of TYPEPGP.CMD already is running
echo If this is in error delete the lockfile
echo "%temp_%\typepgpLockfile.tmp"
if not defined cmdbox if defined PauseIfFromDesktop pause
endlocal & set "%1=true" & goto :EOF)
echo Lockfile "%temp_%\typepgpLockfile.tmp" for TYPEPGP.CMD>"%temp_%\typepgpLockfile.tmp"
endlocal & set "%1=" & goto :EOF
:ProgramHelp
echo Usage: TYPEPGP [Filename^|/switch]
echo /1 = C:\_F\MYFOLD\MYLIST\PRIVATE.PGP
echo /2 = C:\_F\MYFOLD\MYLIST\QTLIST.PGP
echo /3 = C:\_F\MYFOLD\MYLIST\LOCALADM.PGP
echo /4 = C:\_D\MAIL\MYREGIS.PGP
echo.
echo To preset the password you can first use
echo SET PGPPASS=YourPassword
echo Afterwards it is prudent to erase the history e.g. with ALT-F7
goto :EOF
There are a number of re-usable subroutines on these FAQ pages,
including for example
Furthermore, see e.g.
of this FAQ collection.