How Windows 98 Processed Batch Files

In Microsoft Windows 98, batch files (.bat) were executed using the legacy 16-bit command interpreter COMMAND.COM, which ran on top of the underlying MS-DOS 7.1 architecture. Unlike modern 32-bit and 64-bit Windows operating systems that use cmd.exe, Windows 98 processed batch scripts by interpreting plain text commands sequentially through a Virtual 8086 mode environment. This article breaks down the technical execution model, internal parsing mechanics, control-flow logic, and memory structures Windows 98 used to run these scripts.

The Execution Environment: COMMAND.COM and Virtual DOS Machines

When a user launched a .bat file in Windows 98—either from an open MS-DOS prompt or by double-clicking it in Windows Explorer—the operating system initialized a Virtual DOS Machine (VDM).

  1. Interpreter Selection: Windows 98 did not utilize cmd.exe for native batch processing; it invoked COMMAND.COM.
  2. PIF File Settings: When executed from the GUI, Windows 98 checked for an associated Program Information File (.pif). The .pif dictated environment settings, such as conventional and expanded (EMS/XMS) memory allocation, screen font size, and whether the terminal window should close automatically upon script termination.
  3. Virtual 8086 Mode: The CPU transitioned into Virtual 8086 mode to emulate the real-mode execution of MS-DOS, granting the shell access to standardized interrupt services such as INT 21h.

Step-by-Step Script Parsing

COMMAND.COM did not compile batch files or load the entire script into memory before execution. Instead, it operated as a basic, line-by-line interpreter:

  1. File Pointer Tracking: The interpreter opened the .bat file via standard DOS file handles, read a single line up to a carriage return/line feed (CRLF), noted the byte offset for the next line, and closed or preserved the file pointer.
  2. Environment Variable Expansion: Before parsing the command, COMMAND.COM performed token replacement. Any token surrounded by percent signs (such as %PATH%) was matched against the 16-bit environment block and substituted with its current string value. Positional parameters (%0 through %9) were populated from the command-line arguments passed into the script.
  3. Whitespace and Redirection Stripping: The line was scanned for input/output redirection operators (<, >, >>) and pipe characters (|). Pipes were handled by writing output to temporary files on disk and piping them into subsequent processes, rather than using true in-memory Unix-style streaming.

Execution of Commands

Once a line was sanitized and variables were expanded, COMMAND.COM determined how to execute the command:

  • Internal Commands: Directives like DIR, COPY, ECHO, IF, and SET resided directly within the COMMAND.COM binary. These executed immediately in memory without spawning new processes.
  • External Programs: If the command matched an executable file (.exe, .com) located in the current directory or the system %PATH%, COMMAND.COM loaded the binary into memory using MS-DOS Exec functions (INT 21h, AH=4Bh), pausing script interpretation until the external program exited and returned an exit code.
  • Chaining vs. Calling Other Batch Files: If a script called another .bat file directly without the CALL command, COMMAND.COM transferred control entirely to the new script. Because the interpreter only maintained a single execution pointer per instance, it discarded the state of the initial script. Using CALL script2.bat forced COMMAND.COM to maintain state, run the secondary script, and return to the original file when complete.

Control Flow and Branching

Windows 98 handled conditional branching and navigation through rudimentary sequential scanning:

  • GOTO Operations: Because scripts were interpreted line-by-line without an Abstract Syntax Tree (AST), executing a GOTO :LABEL caused COMMAND.COM to reset the file pointer to the beginning of the .bat file and scan downward line by line until it found the matching label string preceded by a colon. In large batch files, this mechanical search caused noticeable latency.
  • Error Level Handling: Windows 98 evaluated program success using IF ERRORLEVEL n. The interpreter checked whether the exit code of the last executed command was greater than or equal to n, allowing basic branching logic based on process success or failure.

Termination and Clean-up

When COMMAND.COM encountered the physical end of the file, an explicit EXIT command, or a Ctrl+C interrupt from the user:

  1. The file handle tied to the .bat file was permanently closed.
  2. Any temporary files created to support pipe chains were removed.
  3. If the script was launched from a GUI shortcut and the "Close on exit" property was checked in the .pif settings, the Virtual DOS Machine was destroyed, and the Win32 window closed. If unchecked, the window remained visible with the prefix "[Finished]" appended to the title bar.