BATCH FILE TIPS AND UTILITIES The Third in a series by Mitchell A. Hoselton THE DOS ENVIRONMENT This month the topic is nominally AUTOEXEC.BAT, but the first order of business is actually the DOS environment. The DOS environment is simply an area in main memory for storing string variables. By default, the size of the DOS environment is 256 bytes in DOS 6.0. In earlier DOS versions the default environment size was 160 bytes. Each program in memory, including Terminate-and-Stay-Resident programs (TSRs for short), gets a copy of the DOS environment. To be precise, each program gets a copy of all the DOS environment variables. To conserve memory, the size of the environment each program gets is only just large enough to hold the current variable names and values. DOS rounds each copy of the environment up to the next integer multiple of 16 bytes or to 160 bytes, whichever is larger. This is the reason why it is important to limit the number of DOS environment variables created prior to loading TSRs into memory. Batch files sometimes require a large primary DOS environment for storing temporary variables. Since DOS only loads the occupied part of the primary environment with each TSR, a large primary DOS environment does not have to waste a lot of memory. In the early days of the PC, before Microsoft documented the DOS environment, a 160 byte environment provided plenty of room. Hardly anyone except Microsoft used it for anything. Today, 160 bytes is inadequate and in DOS 6.0 Microsoft increased the default size to 256 bytes. Batch file programs store permanent and/or temporary variables in the DOS environment. DOS stores the PROMPT and PATH variables there. Increasingly, applications look for DOS environment variables as pointers to directories where users keep their data files. The importance of the role played by the DOS environment continues to grow. Now, the first thing everyone needs to know about the DOS environment is how to make it bigger. INCREASING THE DOS ENVIRONMENT SIZE It is easy to increase the DOS environment size. It requires adding one line to the CONFIG.SYS file on computers running DOS 3.0 or higher. The example of CONFIG.SYS last month contained a line to increase the DOS environment to 656 bytes. (The DOS environment size has to be an integer multiple of 16 bytes.) The syntax of the line in CONFIG.SYS that increases the DOS environment size for each of the DOS versions starting with DOS 3.0, appears in LISTING 1. ============================================================================ LISTING 1 - Syntax for the SHELL Command in DOS Versions 3.0 to 6.0 DOS Version CONFIG.SYS Syntax ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DOS 3.0 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:xx /p DOS 3.1 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:xx /p DOS 3.2 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:yyyy /p DOS 3.3 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:yyyy /p DOS 4.0 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:yyyy /p DOS 6.0 SHELL=[[d:]\path1]\COMMAND.COM [[d:]\path2\] /e:yyyy /p ============================================================================ For information about the SHELL command and COMMAND.COM see the June 1988 issue of BYTE Magazine, page 189; the December 25, 1990 issue of PC Magazine, page 445; the December 1990 issue of Compute, page PC-9; "MS-DOS Batch File Programming - 2nd Edition" by Ronny Richardson, page 329; "DOS Power Tools - Techniques, Tricks and Utilities, 2nd Edition" by Paul Somerson, page 141; "MS-DOS Batch File Utilities" by Ronny Richardson, pages 334-335; and "Microsoft MS-DOS User's Guide and Reference" for DOS 5.0, pages 384-386 (COMMAND.COM) and 566-567 (SHELL). In the SHELL command, [[d:]\path1] specifies the DOS drive and the DOS directory path to COMMAND.COM, [[d:]\path2\] specifies the drive and path where DOS should look for COMMAND.COM when the transient portion needs to be reloaded. The SHELL command must include this parameter if COMMAND.COM is not in the root directory. It sets the COMSPEC environment variable. The xx is a two digit number between 10 and 62, inclusive, and represents the number of 16-byte paragraphs in the DOS environment. The yyyy is a 3, 4 or 5 digit number between 160 and 32,768, inclusive, and represents the number of bytes in the DOS environment. The best size for the DOS environment on a given PC depends on the jobs it is going to do. For most users not currently running DOS 6.0, an immediate increase to 256 bytes is in order. It will be necessary to increase the size beyond 256 every time an "Out of environment space" error message occurs. In this series, the DOS environment is going to get a thorough workout. A DOS environment size of 512 bytes is the minimum that serious batch file programmers should consider. THE CONTENTS OF THE DOS ENVIRONMENT Part of a typical DOS environment might look like LISTING 2. ============================================================================ LISTING 2 - Example of the contents of a typical DOS Environment COMSPEC=C:\COMMAND.COM BOOTCON=A PROMPT=$p$g PATH=C:\;C:\DOS_620 NU=C:\NORTON\ADV_601 XTGTEMP=n:\tempfile TEMP=n:\tempfile TMP=n:\tempfile ============================================================================ My full DOS environment contains 30 permanent environment variables and consumes 588 bytes. A DOS environment variable consists of the environment variable name, followed by an equal sign (=), followed by the value of the environment variable. All environment variables have string values. Even the numerals appearing in the variable value are simple string characters. DOS cannot perform arithmetic with environment variables. Each character in the environment variable's name, the equal sign following the variable name, and each character in the environment variable's value consumes one byte of the environment space. Short names and short values are definitely preferred. ENTERING AND REMOVING ENVIRONMENT VARIABLES FROM THE DOS ENVIRONMENT BOOTCON, the configuration swapping device driver introduced last month, created the DOS environment variable named BOOTCON. BOOTCON has a value of "A" because the user selected the first menu definition block. BOOTCON assigns a value to its namesake environment variable that matches the users chosen configuration. Other DOS environment variables come from a variety of sources. For example, DOS always places the variable named COMSPEC in the DOS environment and, by default, gives it the value "C:\COMMAND.COM whenever the PC boots up from the hard disk. The SHELL command can change the COMSPEC value. The SET command can also change the value of COMSPEC. PROMPT and PATH are special DOS environment variables that are user defined. To create these variables, enter the word PROMPT or PATH at the command line or on a line in a batch file. Follow the command with a space (or an equal sign) and the desired value of the variable. The syntax for creating all other DOS environment variables is as follows. SET variable_name=variable_value Using this syntax, the SET command can create DOS environment variables with almost any name and almost any value. The SET command can change the value of any variable as often as required. The SET command can also delete variables from the DOS environment at any time. Print the current contents of the entire DOS environment on the screen by typing the single word SET at the DOS prompt. (To try these commands at the DOS prompt, always press the [RETURN] to start the command processor after typing the command on the command line.) If there are too many variables in the DOS environment to fit on one screen, then use the following command. SET |more It will display the DOS environment one page at a time. To redirect the environment list from the screen to a file on the disk, use the next command. SET >filename.txt To print out a copy, redirect the output to the printer using this command. SET >prn DOS itself uses the DOS environment variables COMSPEC, DIRCMD, PATH, PROMPT, TEMP and TMP. Other programs will use specifically named DOS environment variables for specific purposes. For example, the Norton Utilities will seek out and use the DOS environment variable NU. XTreeGold will use the DOS environment variable XTGTEMP. Batch file programmers can use the DOS environment to save temporary values and to pass data between batch files. To remove a DOS environment variable from the DOS environment, type the following command. SET variable_name= That SET command clears the variable_value and deletes the variable_name from the DOS environment. The variable_name, the equal sign and the variable_value consume one byte of the DOS environment for each character they contain. It is good practice to remove temporary environment variables from the DOS environment when they have no further use. This makes room for additional environment variables. Removing COMSPEC from the DOS environment may cause the PC to crash. TESTING THE VALUE OF DOS ENVIRONMENT VARIABLES IN BATCH FILES Using batch file commands, it is easy to test the value of environment variables. Following that test, it is easy to alter the order of execution based on the results. The instrument for testing environment variables is the IF command. The IF command has many uses. For our purposes here, the principle uses are the "IF-equal" and the "If-NOT-equal" tests. Try to think of them as the "IF-same-string" and "IF-NOT-same-string" tests. The syntax for each of these two command sequences is as follows. IF "%variable_name%"=="string_to_test" command_to_execute and IF NOT "%variable_name%"=="string_to_test" command_to_execute The percent signs (%) must appear where shown. The variable_name with leading and trailing percent signs tells DOS to substitute the current variable_value in place of the variable_name before processing the command. Omitting the quotation marks is permissible, but including them is better. Do not add any quotation marks other than the ones shown. The command_to_execute executes when the results of the IF test are true. An IF test is true when the variable_name and the string_to_test satisfy the specified test condition. In the first case that means that the value of the environment variable is the same as the string_to_test. In the second case, it means that the value of the environment variable is not the same as the string_to_test. Remember that each variable has both a name and a value. This is a test of the value even though it is the variable's name that appears in the IF statement. When the IF test is false, the next line of the batch file executes, instead of the command_to_execute. The command_to_execute can be almost any DOS command. The examples below just happen to use ECHO commands. A very popular command_to_execute is the GOTO command. GOTO moves the point of execution to another place in the batch file. Normal line by line execution continues from that point down through the batch file. The GOTO command syntax looks like this. GOTO label_name The name that appears in label_name must exist somewhere in the same batch file preceded by a colon (:). The :label_name must occupy a line by itself. The best way to demonstrate all this is with some examples. The method is very general and in the examples in LISTING 3 it is only incidentally that BOOTCON is the variable_name being tested. The examples assume that if BOOTCON=B; #1) a specific command will execute, #2) a specific command will NOT execute, #3) several lines of code will execute and #4) several lines of code will NOT execute. The results are based solely on the value of the BOOTCON variable. ============================================================================ LISTING 3 - Four Examples that test the BOOTCON Environment Variable EXAMPLE #1: a specific ECHO command that executes when BOOTCON loads the second configuration: IF "%bootcon%"=="B" ECHO BOOTCON loaded the second Configuration. EXAMPLE #2: a specific ECHO command that does not execute when BOOTCON loads the second configuration: IF NOT "%bootcon%"=="B" ECHO BOOTCON didn't load the 2nd Config. EXAMPLE #3: a consecutive set of batch file commands that execute when BOOTCON loads the second configuration: IF NOT "%bootcon%"=="B" GOTO go_there ECHO These lines execute when BOOTCON loads the 2nd configuration. ECHO If BOOTCON loads another configuration, the GOTO command moves ECHO the execution pointer to the line below the label_name on the ECHO next line. :go_there EXAMPLE #4: a consecutive set of batch file commands that will not execute when BOOTCON loads the second configuration: IF "%bootcon%"=="B" GOTO go_there ECHO These lines execute when BOOTCON loads any configuration except ECHO the second one. If BOOTCON loads the second configuration, the ECHO GOTO command moves the execution pointer to the line below the ECHO label_name on the next line. :go_there ============================================================================ Study these examples carefully. Working with single and multiple commands requires using the NOT parameter in two distinct ways . Using a series of tests like these, it's possible to construct an AUTOEXEC.BAT file that executes separate and specific sections of the file for each of the specific configurations defined by different BOOTCON menu definition blocks. LISTING 4 shows the schematic organization of such an AUTOEXEC.BAT file. ============================================================================ LISTING 4 - Scheme for AUTOEXEC.BAT that responds to the BOOTCON Configuration Start of AUTOEXEC.BAT file \ Run all the early commands no matter which configuration BOOTCON loaded. / IF NOT "%bootcon%"=="A" GOTO skip_a \ Run commands in this section only if BOOTCON loaded the first configuration (A). / :skip_a IF NOT "%bootcon%"=="B" GOTO skip_b \ Run commands in this section only if BOOTCON loaded the second configuration (B). / :skip_b IF NOT "%bootcon%"=="C" GOTO skip_c \ Run commands in this section only if BOOTCON loaded the third configuration (C). / :skip_c \ Run all remaining commands no matter which configuration BOOTCON loaded. / ============================================================================ CHECKING FOR DEVICE DRIVERS WITH ISDEV The AUTOEXEC.BAT outlined in LISTING 4 will work. If the differences between the BOOTCON configurations involve loading or not loading only a small number of device drivers, or if the order of the menu definitions blocks in CONFIG.SYS is likely to change frequently, then there is a better way to write the AUTOEXEC.BAT file. For example, with as few as four device drivers to load in CONFIG.SYS, it is possible to construct 16 different configurations in CONFIG.SYS. There is one way to load no device drivers, four ways to load one driver, six ways to load two drivers, four ways to load three drivers, and one way to load all four drivers. (This assumes that the loading order inside a each menu definition block is not important. It requires even more tests if the order is important.) Rather than test 16 different values of the BOOTCON variable, it is simpler to test for the four device drivers. The keys to making such a scheme work are finding the batch file utility that tests for the presence of installed device drivers, and finding the names of the installed device drivers to test for. Installed device drivers almost always have installed names that are different from the file names that appear on the DEVICE= lines in the CONFIG.SYS file. The first utility we need is ISDEV. I'll finish this report by describing how ISDEV works. Next month I'll describe a technique for creating ISDEV using the DOS DEBUG command. The second utility that we need is Manifest, from Quarterdeck Office Systems. The command syntax for ISDEV has two forms, as follows. ISDEV d: or ISDEV device_driver_name The parameter d: is the drive letter of a diskette, hard disk partition or RAM drive and device_driver_name is the installed name of a device driver. CONFIG.SYS installs the device drivers. DOS uses drive names internally just like it uses installed device driver names. ISDEV can check for DOS drives just like it does any installed device_driver_name. ISDEV sets a system variable called the exit code to zero (0) if it finds the listed device_driver_name or drive letter. It sets the exit code to one (1) if it does not find the listed drive letter or device_driver_name. In batch files, the IF command uses the ERRORLEVEL parameter to test the value of the most recently issued exit code. The syntax for this version of the IF command looks like one of the following. IF ERRORLEVEL test_value command_to_execute or IF NOT ERRORLEVEL test_value command_to_execute Test_value is a numerical value that DOS compares with the current value of the exit code. Exit codes take values from 0 to 255. The IF ERRORLEVEL command compares the value of the exit code with the test_value. The IF ERRORLEVEL test_value test is true, and command_to_execute executes, only if the exit code is greater than or equal to test_value. The IF NOT ERRORLEVEL test_value test is true, and the command_to_execute executes, only if the exit code is less than the test_value. This may seem unnecessarily complicated, but a couple of examples should help. First, a list of device driver names, that are readily available, appears in LISTING 5. MANIFEST, a program available from Quarterdeck Office Systems, can read the installed device driver names. MAX, a similar program available from Qualitas, could have been used to obtain these installed device driver names. ============================================================================ LISTING 5 - Some Installed Device Driver Names Installed Driver Name Program that installs the named device driver ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EGA$ DOS 5.0's EGA.SYS EMSXXXX0 DOS 5.0's EMM386.EXE expanded memory manager XMSXXXX0 DOS 5.0's HIMEM.SYS extended memory manager SETVERXX DOS 5.0's SETVER.SYS SMARTAAR DOS 5.0's SMARTDRV.SYS disk cache EMMXXXX0 QEMM386 and 386MAX extended memory managers QEMM386$ QEMM386 expanded memory manager 386MAX$$ 386MAX expanded memory manager PC$MOUSE LogiTech or Mouse System's MOUSE.SYS MS$MOUSE Microsoft's MOUSE.SYS $BC$ BOOTCON.SYS driver ============================================================================ It is not possible to use ISDEV to test for the device driver names of DOS's ANSI.SYS, DOSKEY.COM, PRINTER.SYS or DISPLAY.SYS. Each of these drivers uses the name CON or PRN as its installed driver name. ISDEV always finds the devices named CON, PRN, AUX and NUL, whether CONFIG.SYS installs any device drivers. These names are always present because DOS uses them internally. LISTING 6 contains the schematic version of an AUTOEXEC.BAT file that tests directly for the presence of four specific device drivers and executes specific commands for each driver that is present. ============================================================================ LISTING 6 - AUTOEXEC.BAT that uses ISDEV to respond to changing Configurations Start of AUTOEXEC.BAT file \ Run all the early commands no matter which device drivers BOOTCON loaded. Then change to the drive and directory containing ISDEV.COM. / ISDEV QEMM386$ IF ERRORLEVEL 1 GOTO skipqemm \ Run commands in this section only if CONFIG.SYS loaded QEMM386. / :skipqemm ISDEV 386MAX$$ IF ERRORLEVEL 1 GOTO skipmax \ Run commands in this section only if CONFIG.SYS loaded 386MAX. / :skipmax ISDEV N: IF ERRORLEVEL 1 GOTO no_n_drv \ Run commands in this section only if RAM drive N: exists. / :no_n_drv ISDEV PC$MOUSE IF ERRORLEVEL 1 GOTO no_mouse \ Run commands in this section only if CONFIG.SYS loaded the LogiTech Mouse driver. / :no_mouse \ Run all remaining commands no matter which device drivers CONFIG.SYS loaded. / ============================================================================ To avoid execution of a series of commands when a specific device driver is installed, use the following command after ISDEV. It will force the execution pointer to skip over a series of command lines. IF NOT ERRORLEVEL 1 GOTO label_name Next time, we'll create the ISDEV.COM program using DEBUG. That article will introduce the use of script files to create short utilities. Typing in a short script by hand is often easier than downloading the utility from a bulletin board. Using script files introduces the potential hazard that typos might create a rogue program. However, a script file can be proof-read and edited as many times as it takes to get it right. With care, typos are not a problem. Using, even correctly typed, scripts with DEBUG has a few minor hazards. These are simply a matter of practice and are very easy to avoid. Whenever possible, scripts will provide easy access to the small utilities introduced in this series. KEY WORDS 386MAX$$ (386MAX Expanded Memory Manager) ANSI.SYS AUTOEXEC.BAT AUX Batch File Program BOOTCON Bulletin Board BYTE Magazine - June 1988 COMMAND.COM COMMAND.COM - transient portion Command_to_Execute COMPUTE magazine - December 1990 COMSPEC CON CONFIG.SYS DEBUG Default Environment Size Device Driver DEVICE= Device_Driver_Name DIRCMD Diskette DISPLAY.SYS DOS DOS Environment DOS Power Tools-Techniques, Tricks, and Utilities, 2nd Edition by Paul Somerson DOSKEY.COM Downloading d: ECHO EGA$ (DOS 5.0's EGA.SYS Device Driver) EMMXXXX0 (386MAX and QEMM386 Extended Memory Managers) EMSXXXX0 (DOS 5.0's EMM386.EXE Device Driver) Environment Environment Variable Name (Variable_Name) Environment Variable Value (Variable_Value) Error Message ERRORLEVEL Parameter Exit Code GOTO Hard Disk Partition IF IF ERRORLEVEL IF NOT ERRORLEVEL IF NOT == (IF NOT equal) IF == (IF equal) ISDEV.COM Label_Name Main Memory MANIFEST Microsoft [Corporation] Microsoft MS-DOS User's Guide and Reference, for DOS 5.0 MORE MS-DOS Batch File Programming - 2nd Edition, by Ronny Richardson MS-DOS Batch File Utilities, by Ronny Richardson MS$MOUSE (Microsoft MOUSE.SYS) NU (Norton Utilities) NUL Paragraph (16 bytes) PATH Paul Somerson PC Magazine - December 25, 1990 PC (Personal Computer) PC$MOUSE (LogiTech or Mouse Systems MOUSE.SYS) Primary DOS Environment PRINTER.SYS PRN PROMPT QEMM386$ (QEMM386 Expanded Memory Manager) Qualitas Quarterdeck Office Systems RAM DISK Script File SET SETVERXX (DOS 5.0's SETVER.SYS Device Driver) SHELL SMARTAAR (DOS 5.0's SMARTDRV.SYS Device Driver) String Value String Variable String_to_Test TEMP Temporary Variable Test_Value TMP Transient Portion of COMMAND.COM TSR (Terminate-and-Stay-Resident Program) Variable_Name (Environment Variable Name) Variable_Value (Environment Variabl Value) XMSXXXX0 (DOS 5.0's HIMEM.SYS Devic Driver) XTGTEMP (XTreeGold) $BC$ (BOOTCON.SYS Device Driver)