A) How does Windows command processor search for commands?
Windows command processor searches for a COMMAND to execute which
- is not an internal command of
- is just specified with file name without file extension and without path
for a file matching the pattern
command.* and having a file extension listed in local environment variable
- first in current directory and
- next in all directories of local environment variable
SORT and FIND and FINDSTR and ROBOCOPY and XCOPY and many more commands are not internal commands of
cmd.exe. They are console applications installed with Windows located in directory
%SystemRoot%\System32 having the file name
Such console applications available by default on Windows are called external commands to distinguish them better from console applications not installed with Windows operating system.
B) How is the environment variable PATH defined?
There are three types of
PATHwhich is used for all accounts and stored in Windows registry under key:
PATHwhich is used only for current account and stored in Windows registry under key:
PATHwhich is always a copy of the local
PATHof parent process which started the current process.
Windows concatenates system and user
PATH to local
PATH for the Windows Explorer instance used as Windows desktop with the shortcuts on the desktop screen and the Windows start menu and the Windows taskbar as visible interface for the user called Windows shell from which users usually start programs.
The entire currently active environment variables list of running process is copied for the new process by Windows on starting a new process. The Windows kernel library function CreateProcess does this environment variables list copy from the memory of the current process to the memory of the new process on function parameter
lpEnvironment (long pointer to environment) being a null pointer. One of the
CreateProcess functions is always used on Windows on starting an executable from another executable.
The parent process cannot modify the environment variables of any child process nor can a child process modify the environment variables of its parent process.
This means once a process like
cmd.exe was started for execution of a batch file, the process has its own set of environment variables which only the process itself can modify. No other process can modify the environment variables of an already running process.
C) What does the error message mean?
The error message
‘…’ is not recognized as an internal or external command,
operable program or batch file.
always means that
the file name of a
- console application
- GUI application
- script (batch file, PowerShell script, Perl script, VBScript, JScript, …)
was specified for execution most likely without file extension and without (complete) path to the executable/script file and
Windows failed to find a file matching the pattern
FileName.*with a file extension listed in currently active environment variable
PATHEXTin current directory or any other directory in currently active environment variable
D) What are the possible reasons for this error message?
Typical reasons are:
1. The file name of the file to execute was specified wrong due to a typing mistake.
Check character by character the name of the command/executable.
2. The current directory is different to the directory containing the file to execute.
echo Current directory is: %CD% on command line or add this line to the batch file above the command line which fails to see what the current directory is.
3. The executable or script to run is not installed at all.
Verify the existence of the executable to run. Some installation packages work only if other packages like Java, NPM, PHP, etc. were installed before.
4. The directory of the file to execute is not in
PATH at all.
Open in Windows Control Panel the System settings window, click on Advanced system settings on left side, click on button Environment Variables and look in both lists for
Path and their values. By default
Path exists only in list of System variables.
5. A running process/application was not restarted after modification of system or user
A modification of system
PATH or user
PATH with command
setx or via Control Panel – System and Security – System – Advanced system settings – Environment Variables was made by the user or an installer, but an already running process/application like an opened command prompt or PowerShell window was not closed/exited and opened/restarted after
PATH modification. This is necessary as described in detail in chapter F) below.
6. An executable in
%SystemRoot%\System32 is not found on 64-bit Windows.
There is the directory
%SystemRoot%\System32 with 64-bit executables and
%SystemRoot%\SysWOW64 with 32-bit executables on 64-bit Windows with a processor supporting also the x86 instruction set. Most executables exist in both directories. But there are some executables existing only in
System32 and a few only in
PATH contains by default as first folder path
%SystemRoot%\System32. But which one of the two Windows system folders is searched for the executable specified without path or with the path
%SystemRoot%\System32 depends on the execution environment. An application or script executed in 64-bit environment is really accessing
%SystemRoot%\System32 while an application or script executed in 32-bit environment is redirected by the Windows file system redirector to the directory
An application or script running in 32-bit environment which wants to run a 64-bit executable in
%SystemRoot%\System32 has to use the fully qualified file name of the executable with file path
%SystemRoot%\Sysnative is neither a directory nor any type of link. It is something very special existing only for x86 applications. It does not exist for amd64 applications. The condition
if exist %SystemRoot%\Sysnative in a batch file is always false in both environments, but
if exist %SystemRoot%\Sysnative\cmd.exe is true in 32-bit execution environment and false in 64-bit environment and also on 32-bit Windows. This condition can be used in batch scripts to find out if the batch file is processed by 32-bit
%SystemRoot%\SysWOW64 on 64-bit Windows which can be important to know depending on the task.
See also the Microsoft documentations WOW64 Implementation Details and Registry Keys Affected by WOW64.
PATH contains a reference to a not (yet) defined environment variable.
It is possible to specify in
PATH a folder path using a reference to value of another environment variable like
SystemRoot. It is important that this environment variable is also defined in same set of environment variables or a set of environment variables processed first by Windows.
For example if
%JAVA_HOME%\bin is added to system
PATH environment variable, there must be defined also a system environment variable
JAVA_HOME with the base folder path to Java program files. It is not enough to have defined a user environment variable
JAVA_HOME or define the environment variable
JAVA_HOME later in the local environment of a batch file.
%JAVA_HOME%\bin added to user
PATH is expanded by Windows to a full qualified folder path if the environment variable
JAVA_HOME is defined either as system or as user environment variable, but not on
JAVA_HOME defined later in the local environment of a Windows command process.
Such a mistake can be seen easily by opening a new command prompt window after making a modification on system or user
PATH from Windows start menu and running
set path. The output
PATH should not contain anymore any
%Variable% environment variable value reference.
8. The LOCAL variable
PATH was modified before on command line or in batch file.
set path on command line or add this command to the batch file above the command line which fails to see the current values of the environment variables
The last reason is responsible for external command SORT not being found on execution of the batch file which contains somewhere above
E) How to avoid this error message?
Best is coding a batch file for being independent on
PATHEXT and the order of directories in
PATH which means here using the command line:
FOR /f "delims=" %%d in ('dir /s /b /ad ^| %SystemRoot%\System32\sort.exe /r') do rd "%%d"
Any external command of which executable is stored in
%SystemRoot%\System32 should be specified in a batch file with this path and with file extension
.exe. Then Windows command interpreter does not need to search for a file using local
PATHEXT and the batch file works always (as long as environment variable
SystemRoot is not also modified in the batch file which I have never seen).
F) When is a system or user PATH change applied to processes?
When a user opens a command prompt window via Windows start menu or from within a Windows Explorer window, the user starts
cmd.exe with implicit using option
/K to keep the console window open after finishing a command which is good for debugging a batch file.
When a batch file is doubled clicked in Windows Explorer, the user starts
cmd.exe for processing the batch file with implicit using option
/C to close the console window after finishing batch processing which is not good for debugging a batch file as error messages cannot be seen in this case.
In both cases Windows creates a copy of the environment variables of the application starting
cmd.exe which is usually Windows Explorer. Therefore the started command process has a local
PATH of which value is the same as the parent process had on starting
Open a command prompt window, run
title Process1and run
PATHEXTas currently defined for current user account in the console window having now the window title Process1.
set PATH=%SystemRoot%\System32and next once again
Output is again
PATHEXT, but with
PATHcontaining only one directory now.
start "Process2"and run in new console window with window title Process2 the command
PATHEXTwith same values as before in Process1.
This demonstrates that on starting a new process the current environment variables of running process are copied and not what Windows itself has currently stored in Windows registry.
Run in Process2 the command
set PATH=and next
Output is only
PATHdoes not exist anymore for Process2.
This demonstrates that every process can modify its environment variables including complete deletion.
Switch to Process1 window, run the command
set PATH=%PATH%;%SystemRoot%and next
PATHwith two directories and
Run the command
start "Process3"and in opened window with title Process3 the command
PATHwith two directories as defined also for Process1 and
Run in Process3 the command
There are 3 command processes running with following values for local
%SystemRoot% expands to
PATH does not exist at all.
So what happens now on opening Control Panel – System – Advanced System Settings – Environment Variables and adding to list of User variables the new environment variable
PATH with value
C:\Temp, or in case of there is already a user
PATH environment variable, edit
PATH and append
;C:\Temp to the value?
Well, as long as the dialog window with title Environment Variables showing the two lists is opened, nothing happens on modifying the variables, until button OK is clicked to take over all changes into Windows registry and close the window.
Let’s go back to the three running command processes and run in Process1, Process2 and Process3 the command
set path. It can be seen:
PATH does not exist at all.
Nothing changed on already running processes.
No process can modify the environment variables of a different running process!
Open from Windows start menu one more command prompt window and run in fourth command process the command
set path. It can be seen that local
PATH of fourth command process has appended the directory
Then close all four command processes and delete the added user
PATH respectively remove
;C:\Temp from user
PATH if having appended this directory path before.
How is this possible if no process can modify the environment variables of an already running process?
How was the environment variables list of Windows Explorer instance running as Windows desktop modified on closing Environment Variables window with button OK?
The answer on those two questions was given by eryksun in his comment.
After writing the modifications on system and user variables into registry on clicking button OK of Environment Variables window, Windows sends the WM_SETTINGCHANGE message to all top-level windows to inform the running applications about changed system parameters.
It is up to the application if this event message is handled at all and how. Windows Explorer running as Windows desktop reads the environment variables from registry and updates its environment variables list accordingly. Other applications like Total Commander handle this message also and update their lists of environment variables too. But
cmd.exe does not do that fortunately as this would be really problematic.
Is there any possibility to modify a system or user variable with notification via
WM_SETTINGCHANGE from within a command prompt window or batch file?
It is possible to modify the registry value of an environment variable using
reg add command. But this does not result in sending
WM_SETTINGCHANGE message to all top-level windows. Such changes done with
reg add or with
regedit require a restart of Windows (or at least a log off and log on of current user) to be taken into account at all.
But there is also the command
setx which is designed for modifying a system or user variable and which also sends the
WM_SETTINGCHANGE message to all top-level windows after registry was updated according to specified arguments. Run
setx /? in a command prompt window for details. But please take into account that
setx does not modify the local environment variable of running command process. This must be done with using command
set used in addition to
G) How is environment variable PATHEXT handled by Windows?
The environment variable
PATHEXT with the list of file extensions is handled by Windows different in comparison to environment variable
PATHEXT and user
PATHEXT are NOT concatenated to local
PATHEXT replaces the system
PATHEXT for all processes running under environment of the account having defined a user
There is defined only a system
PATHEXT environment variable by default.
H) Is it possible to disable file search in current directory?
Windows command processor searches by default in current directory if file name of a script file or executable is specified on command line or in a batch file without any path which means without a backslash
\ (or a forward slash
/ thanks to auto-correction) in argument string.
But on Windows Vista and later Windows client versions and on Windows Server 2003 and later Windows server versions it is indeed possible to disable searching for a script/executable in current directory specified without at least relative path
.\ by defining the environment variable
NoDefaultCurrentDirectoryInExePath with any value as written by eryksun in his comment below and explained by Microsoft’s documentation about function NeedCurrentDirectoryForExePathA.
See Removing the current working directory from the path for more details on usage of this environment variable.
I) How to modify system or user PATH?
The system and user
PATH environment variables are modified by a user best using the Windows GUI dialog window Environment Variables. This dialog window can be opened as follows:
- Click on the Windows Start menu button.
- Type on keyboard environment variables.
- There are offered by Windows the two items:
Edit the system environment variables
Edit environment variables for your account
- Click on one of the two items to open the Environment Variables window.
There can be also opened the Windows Control Panel. There must be next clicked on System and Security with Category selected for display option View by. Next must be clicked System. There must be clicked on left side Advanced system settings and next on the button Environment Variables…
The System window can be opened also by pressing the key combination Windows logo key + Pause if the keyboard has the key Pause at all or at least in combination with the key Fn. See also the Microsoft documentation page Keyboard shortcuts in Windows.
The further user actions are self-explaining for editing either user
Path in upper list on existing at all or system
Path in lower list.