The Windows command-line interface, part 1
The difference between command lines, command-line programs, and command-line shells.
Published in Articles on by Michiel van Oosterhout ~ 5 min read
Windows 11 may come with a refreshed graphical user interface (GUI), it still needs to provide a solid command-line interface (CLI) for those of us that want to run command-line programs like PowerShell, Git, and Vim.
Between 2015 and 2019 Microsoft invested in the old command-line interface, but reached the limits of what was possible and has since put its efforts into a new command-line interface. We will look at the improvements in part 2, but we first need to define some terminology (pun intended).

Command lines
A command line is a single line of text which starts with the name of a built-in command or path to an executable file, followed by subcommands, options, and arguments 1. For example: git.exe commit -m "Initial commit"
. Here git.exe
is the path to an executable file, commit
is a subcommand, -m
is an option and "Initial commit"
is an argument. Another example: dir C:\Windows /a:hs /p
. Here dir
is the name of a built-in command, C:\Windows
is an argument, /a
is an option, h
and s
are arguments, and /p
is another option. Arguments apply to the token that precedes them, so C:\Windows
applies to the dir
command, whereas h
and s
apply to the /a
option.

dir
command, followed by the command's output
When the first token of a command line is a path to an executable file, the rest of the command line (subcommands, options, and arguments) is parsed by the program itself, typically using a set of conventions (e.g. options start with --
or /
) and using a library like System.CommandLine to follow such conventions.
Command-line programs
A command-line program for Windows is an executable that requires the Windows character subsystem (identified by IMAGE_SUBSYSTEM_WINDOWS_CUI
) to run, as opposed to the Windows graphical user interface (GUI) subsystem (identified by IMAGE_SUBSYSTEM_WINDOWS_GUI
). When a command-line program is started in the Windows Shell, Windows needs to connect the command-line program's input and output to a console or terminal, a GUI program that forwards character input to a command-line program, and renders the command-line program's character output in a Window.
When a command-line program is started by another command-line program (its parent), then Windows connects the command-line program to the parent's console or terminal.

A command-line program can run to completion and exit immediately, but some command-line programs wait for character input to proceed. Text editors like Vim are examples of interactive command-line programs, and so are command-line shells like PowerShell.
Command-line shells
A command-line shell prompts for a command line. The prompt is a series of characters that the shell outputs, often providing some context. For example PS C:\Windows>
informs us that this is a PowerShell prompt, and what the current working directory is. When the command line is entered (literally via the Enter key), the shell executes the built-in command or program specified by the command line. When the command or program exits, control is returned to the shell, which awaits entry of the next command line.
Command-line shells typically support running a batch of command lines stored in a file, with support for control flow using conditional expressions and subroutines. Command-line shells can also provide the output of one command or program as input to the next.
On Windows the main shells are Windows Command Processor 2 (located at $Env:SystemRoot\System32\cmd.exe
) and Windows PowerShell (located at $Env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe
).
Windows Command Processor was designed to be compatible with the MS-DOS shell COMMAND.COM
, and comes with many built-in commands (the dir
example above is one such command). It remains in Windows for backwards compatibility.
PowerShell is a more modern shell, based on .NET, with object-oriented input and output, and an object-oriented scripting language.
Virtual consoles and terminals
A video terminal is a device with a keyboard to enter character input and a screen to render character output, connected via serial to a computer. These were also known as consoles.

Modern operating systems have a graphical user interface, and the command-line interface exists within the confines of that interface. This means there are windows that receive input, forward the input as characters to the command-line program, and render the character output from the command-line program. Historically on Windows the program that creates the window has been Console Window Host (conhost.exe
).
Console Window Host also provides the Console API specifically for command-line programs. The Console API can be used to write characters to a particular location, move the cursor, or change attributes like color or brightness of characters written to the output. Some functions allow for interaction with the Console Window Host, for example to set the title of its window, or change its display mode to full screen (also possible with Alt+Enter). The use of the Console API has made porting Windows command-line programs to other platforms more difficult.
Command-line programs for Unix and Linux use special character sequences in their output to achieve similar effects. These sequences were historically not supported by Console Window Host. This has made porting command-line programs to Windows more difficult.
Part 2 will look at the evolution from Console Window Host to Windows Terminal, and the improvements this has brought to the Windows command-line interface.
Summary
A command line is interpreted by a command-line shell to start a built-in command or a command-line program. The input and output of such commands and command-line programs is character-based. The input is gathered, and the output rendered, by a virtual console or terminal.
-
Windows Command Processor uses the term parameter instead of option and argument. ↩︎
-
Microsoft does not provide official documentation for Windows Command Processor's scripting syntax, but SS64 provides several how-to guides and examples, and the answers to this question on Stack Overflow provide a wealth of information on the topic. ↩︎