Iterating over files in directory prepends extra character to filename - batch-file

For some strange reason this batch script is prepending an extra character to the filename while iterating over the non-hidden files in a directory.
See this example:
Plain-text:
FOR /F %i in ('dir "*.sql" /A-H /b') DO #echo %i
Output:
♀test.sql
This is an issue because when I try to open %i it says it doesn't exist.
I could replace the first character, but this script needs to work on multiple machines and not just mine. This only happens on my machine. Any idea how to fix it?
Update
So 0x0C (form feed?) seems to be the character inserted.

First, take a look on answer on Stack Overflow question Windows batch outputs a line feed female character.
Second, take a look on Microsoft's TechNet article Command Processor\AutoRun, or read in help output after entering cmd /? about AutoRun registry value.
It looks like on the computer on which a form-feed is written first to file on redirecting output of command dir, there is a batch file or another command configured to be automatically executed on start of command line processor. And one of those commands is responsible for the form-feed character.
This can be checked quickly without first looking into Windows registry by starting cmd.exe with option /D and then enter the commands as it can be seen on screenshot in question. If the file file.txt is now without a form-feed as first character, there could be indeed an autorun command responsible for this unwanted behavior.
Start now regedit.exe and check the value AutoRun under
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
and
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
On my computer the value AutoRun does not exist at all in HKCU and is empty in HKLM.
Also run in a command prompt window on this computer just set and look on the environment variables
ComSpec ... should be C:\Windows\System32\cmd.exe
PATHEXT ... should be .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PATH ... should start with C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;
It could be that the command processor on this computer is not cmd.exe or PATH starts with a different folder than System32 directory in Windows directory and this folder contains also a cmd.exe or other console applications which can be found in System32 directory of Windows.
Those 3 very important environment variables can be configured in Control Panel - System - Advanced - Environment Variables according to Environment Variables documentation.

Related

batch to check .net core v5 desktop runtime present on user system (issue) [duplicate]

I have a one-line snippet that works perfectly in the command line, but fails and throws up errors when I run it as part of a batch script.
The below commands behaves as expected, deleting all empty subfolders in the folder.
for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"
However, when put in a batch file like so...
FOR /f "delims=" %%d in ('dir /s /b /ad ^| sort /r') do rd "%%d"
...it throws the standard error:
Sort is not recognised as an internal or external command
I've been experimenting for the last hour or so with and without escaping the pipe, changing the order of the options, looking up the documentation of both dir and sort, etc., but I've still not been able to figure out what's going on here. The rest of the batch file, which is only a few lines, works fine, and this is the only line in it that fails.
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 cmd.exe and
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 PATHEXT
first in current directory and
next in all directories of local environment variable PATH.
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 sort.exe, find.exe, findstr.exe, robocopy.exe, xcopy.exe, ...
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 PATH variables:
System PATH which is used for all accounts and stored in Windows registry under key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
User PATH which is used only for current account and stored in Windows registry under key:
HKEY_CURRENT_USER\Environment
Local PATH which is always a copy of the local PATH of 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 PATHEXT in current directory or any other directory in currently active environment variable PATH.
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.
Run 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 PATH.
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 SysWOW64.
The system 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 %SystemRoot%\SysWOW64.
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.
Note: %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 cmd.exe in %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.
7. 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.
Run 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 PATH and PATHEXT.
That reason is responsible for external command SORT not being found on execution of the batch file which contains somewhere above set path=....
9. LOCAL variable PATH is too long.
The local variable PATH of cmd.exe is too long. The Windows Command Processor fails to find any executable/script in the folder paths of local Path if the string value is longer than 8191 characters.
Please see my second answer here for more details regarding to length limitations of PATH.
Thanks goes to Albert Mosiałek for informing me about this cause of a not recognized program or script.
E) How to avoid this error message?
Best is coding a batch file for being independent on PATH and 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 PATH and 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 cmd.exe.
Example:
Open a command prompt window, run title Process1 and run set path.
Output is PATH and PATHEXT as currently defined for current user account in the console window having now the window title Process1.
Run set PATH=%SystemRoot%\System32 and next once again set path.
Output is again PATH and PATHEXT, but with PATH containing only one directory now.
Run start "Process2" and run in new console window with window title Process2 the command set path.
Output is PATH and PATHEXT with 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 set path.
Output is only PATHEXT because local PATH does 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 set path.
Output is PATH with two directories and PATHEXT.
Run the command start "Process3" and in opened window with title Process3 the command set path.
Output is PATH with two directories as defined also for Process1 and PATHEXT.
Run in Process3 the command set PATH=%SystemRoot%\System32.
There are 3 command processes running with following values for local PATH when %SystemRoot% expands to C:\Windows:
Process1: PATH=C:\Windows\System32;C:\Windows
Process2: PATH does not exist at all.
Process3: PATH=C:\Windows\System32
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:
Process1: PATH=C:\Windows\System32;C:\Windows
Process2: PATH does not exist at all.
Process3: PATH=C:\Windows\System32
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 C:\Temp now.
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 setx.
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 PATH.
System PATHEXT and user PATHEXT are NOT concatenated to local PATHEXT.
A user PATHEXT replaces the system PATHEXT for all processes running under environment of the account having defined a user PATHEXT.
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.
Most probably, you messed around with the PATH variable. Perhaps you are overwriting it somewhere else in your script. Since sort is an external command, opposed to all the others in your command line like for, dir, rd, which are cmd-internal commands, the PATH variable is needed to find the command. If PATH is not defined, external commands are searched in the current working directory only. There is also a PATHEXT variable that is needed to define standard file extensions for executables, like .com, .exe. So when sort appears in command prompt or in a batch file, the system searches the current working directory and all directories specified by the PATH variable for a file with the base name sort and one of the extensions specified by PATHEXT. The command sort is actually called sort.exe and is usually located in C:\Windows\System32.
In my case, I was so sure that I didn't mess with PATH. It was that I wasn't aware that path and PATH are the same. CMD is case insensitive.
This answer contains additional information to my first answer here regarding to length limitations of PATH.
There are not good coded executables/scripts which modify system or user PATH without checking first if the folder path to add is not already in string value of one of the two PATH environment variables as reported by Albert Mosiałek in a comment. Multiple executions of such a program results in local PATH string value of cmd.exe becomes longer and longer until reaching the PATH length limitations.
The maximum length of local PATH string value of cmd.exe depends on version of Windows and multiple string length limitations.
Length limitations of PATH on Windows Vista and Windows 7
Length limitations of system PATH
The system PATH as stored in Windows registry is truncated to its maximum length of 4095 characters before expanding all the environment variable references. The truncated string assigned to local PATH of cmd.exe can be also shorter than 4095 characters on system PATH contains environment variable references like %SystemRoot% (12 characters) expanding to C:\Windows (10 characters) and no user PATH is stored in Windows registry.
The system PATH is truncated to its maximum length of 4095 characters after expansion of the environment variable references. The truncated string assigned to local PATH of cmd.exe can be longer than the string value stored in Windows registry if environment variable references expand to strings which are longer than the environment variable reference strings.
In worst case the system PATH is truncated twice to a maximum length of 4095 characters, the first time before and the second time after expansion of the environment variable references.
Length limitations of user PATH
The user PATH is ignored completely independent on length of system PATH if the string value stored in Windows registry is longer than 4095 characters.
The user PATH is appended with an additional semicolon in expanded form to local PATH of cmd.exe on being in Windows registry not longer than 4095 characters even if the user PATH is in expanded form longer than 4095 characters because of environment variable references like %APPDATA%, %LOCALAPPDATA% or %USERPROFILE%.
The local PATH of cmd.exe can reach the maximum length of 8191 characters in worst case with a very long and perhaps already once or twice truncated system PATH and a user PATH not longer than 4095 characters in Windows registry, but longer than 4095 characters in expanded form.
The Windows Command Processor cmd.exe stops finding any executable on local PATH becomes too long, for example if the system PATH of 4095 characters in registry expands to a string with 4087 characters and is concatenated with a semicolon and a user Path stored in Windows registry with 4074 characters, but is expanded to a string value of length 4104 characters, resulting in a local Path with a total length of 8192 characters. There is not even found anymore any executable in %SystemRoot%\System32 on local PATH string value has a length of 8192 characters although the execution of set path outputs the local PATH with first directory path C:\Windows\System32.
There is the Command prompt (Cmd. exe) command-line string limitation which means that the environment variable name PATH plus equal sign = plus the variable string value plus the string terminating null byte must fit into a character array of 8192 characters. The string value of the local environment variable PATH as output on running set path in a command prompt window cannot be longer than 8186 characters for that reason although in memory the string value of local Path can be up to 8191 characters.
The internal command SET of cmd.exe does not output anymore a line-feed on running set path in a command prompt window if the local PATH has a string value of 8186 or more characters. In the console window is displayed for that reason in this case the environment variable PATHEXT with the equal sign and its string value appended to end of the string value of the environment variable PATH.
Length limitations of Control Panel windows for editing environment variables
A user or system PATH or any other in Windows registry persistent stored environment variable with a string value longer than 4094 characters is not displayed in the Environment Variables dialog window. For a user it looks like the environment variable does not exist which has a string value with more than 4094 characters although the environment variable is stored in registry and is perhaps even defined in local environment of running processes. The other user and system variables are still displayed in the Environment Variables window.
The Edit User Variable and Edit System Variable dialog windows display a Variable value with up to 4094 characters. A user can delete characters from such a long string value and save the shortened string value. But a user cannot append characters or replace existing characters on string value of the environment variable is longer than 2047 characters. A user can edit for that reason a user or system environment variable PATH with a string value longer than 2047 characters only for removal of a directory path using the Environment Variables window of Control Panel, but not for changing characters of an existing directory path or adding one more directory path to the environment variable string which is longer than 2047 characters.
Recommendations for PATH lengths
The system as well as the user PATH as stored in Windows registry and in their expanded form should be never longer than 4094 characters on Windows Vista and Windows 7 and are best both shorter than 2048 characters to be editable in the Control Panel windows.
Length limitations of PATH on Windows XP
Length limitations of system PATH
The system PATH as stored in Windows registry is truncated to its maximum length of 2047 characters before expanding all the environment variable references. The truncated string assigned to local PATH of cmd.exe can be also shorter than 2047 characters on system PATH contains environment variable references like %SystemRoot% (12 characters) expanding to C:\Windows (10 characters) and no user PATH is stored in Windows registry.
The system PATH is truncated to its maximum length of 2047 characters after expansion of the environment variable references. The truncated string assigned to local PATH of cmd.exe can be longer than the string value stored in Windows registry if environment variable references expand to strings which are longer than the environment variable reference strings.
In worst case the system PATH is truncated twice to a maximum length of 2047 characters, the first time before and the second time after expansion of the environment variable references.
Length limitations of user PATH
The user PATH is ignored completely if the expanded system PATH concatenated with the expanded user PATH with an additionally inserted semicolon results in a string value longer than 2047 characters. The maximum length of the user PATH on Windows XP depends for that reason on current length of expanded system PATH.
Length limitations of Control Panel windows for editing environment variables
A user or system PATH or any other in Windows registry persistent stored environment variable with a string value longer than 4095 characters is not displayed in the Environment Variables dialog window. For a user it looks like the environment variable does not exist which has a string value of more than 4095 characters although the environment variable is stored in registry and is perhaps even defined truncated in the local environment of running processes. The other user and system variables are still displayed in the Environment Variables window.
The Edit User Variable and Edit System Variable dialog windows display a Variable value with up to 2047 characters. A user can edit an even longer string value and save the string value, but the string value is always truncated to a maximum length of 2047 characters as displayed in edit field of the window. A user cannot append characters or replace existing characters on string value of the environment variable is longer than 2047 characters.
Recommendations for PATH lengths
The system PATH as stored in Windows registry and in its expanded form should be never longer than 2047 characters on Windows XP.
The user PATH in its expanded form should be short enough to be not ignored on concatenating it with the system PATH.

Pass multiple variables to binary

In unix command line you can do this
tempvar=ABC mybinary
apparently you can do the same in Windows batch, but in case you need multiple assignments to pass, export in unix would do the trick. How could you pass multiple variables to mybynary in a Windows Batch script?
1. Information about Windows commands and Windows command processor syntax
There can be executed help in a command prompt to get output an incomplete list of Windows commands with a brief description. Any Windows command can be executed with /? as argument to get output the usage help for the command. The execution of cmd /? results in output of the usage help of Windows command processor cmd.exe which is the Windows equivalent for man sh (or man bash, man dash, man ksh, man zsh, etc.) in a Linux terminal window.
For most Windows commands, but not all of them, it is also possible to run help with the command name as argument. help set and set /? output both the usage help of the command to define environment variables.
There is additionally:
the Microsoft documentation about the Windows commands
the A-Z index of Windows CMD commands by SS64
the Windows CMD Shell How-to guides and examples by SS64
SS64 offers also comprehensive documentations for other scripting languages on Windows, Linux and Mac.
There are two types of Windows commands:
the internal commands of cmd.exe like echo, copy, set
the so called external commands like chcp, find, robocopy
The external Windows commands are executables in directory %SystemRoot%\System32 with file extension .com like chcp.com (rare) or file extension .exe like find.exe, robocopy.exe and where.exe (most external Windows commands).
There are on 64-bit Windows two system directories:
%SystemRoot%\System32 contains the 64-bit executables and dynamic linked libraries.
%SystemRoot%\SysWOW64 contains the 32-bit executables and dynamic linked libraries.
The Windows commands usually exist in both system directories as 32-bit and 64-bit executable on 64-bit Windows. But there are some executables existing only as 64-bit executables.
That is important to know if a 32-bit application starts on 64-bit Windows the Windows command processor cmd.exe to process a batch file because of the File System Redirector starts in this case 32-bit %SystemRoot%\SysWOW64\cmd.exe and all commands found via the environment variables PATHEXT and PATH in folder %SystemRoot%\System32 being by default the first folder path in system environment variable PATH are in real searched and executed from directory %SystemRoot%\SysWOW64 in the 32-bit execution environment on 64-bit Windows.
In a command prompt window are entered by a user a command usually with just its file name and so the Windows command processor has to search for a suitable file to execute. For details about this process read: What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?
In a batch file can be used also only the file name of an external Windows command, but it is advisable to specify them with full qualified file names for the following reasons:
The batch file an external command specified like %SystemRoot%\System32\find.exe instead of just find are more fail safe and secure as the batch file does not depend on the environment variables PATHEXT and PATH defined outside of the batch file which are quite often modified by programs and users, especially the environment variable PATH.
The batch file is executed faster as the Windows command processor has not to search in file system for the executables.
The external Windows command where can be used to find out if a Windows command is an internal command or an external command. The execution of where set in a command prompt window results in output of an error message (hopefully) while where find results in output of file qualified file name of find (hopefully found first in %SystemRoot%\System32 with file extension .exe).
2. Define one or more environment variables for an executable
The command to define environment variables on Windows is SET. So this command must be used to define an environment variable which an executable evaluates on execution. An environment variable like tempvar can be defined as follows:
set tempvar=ABC
set "tempvar=ABC"
The second syntax is highly recommended, but requires enabled command extensions which is the case by default, but which does not mean that command extensions are always enabled. Please read my answer on: Why is no string output with 'echo %var%' after using 'set var = text' on command line? There is explained in full details why set "variable=value" is the recommended syntax.
The environment variable(s) evaluated by an executable can be defined on separate lines before execution of the executable or on same command line.
Definition of the environment variable and execution of the executable on separate command lines:
set "tempvar=ABC"
mybinary
Definition of the environment variable and execution of the executable on one command line:
set "tempvar=ABC" & mybinary
Single line with multiple commands using Windows batch file explains the operator & used in the single command line variant.
A batch file writer should avoid replacing one of the predefined Windows environment variables, except a predefined environment variable should be intentionally redefined in a batch script.
3. Define one or more environment variables just for an executable
Environment variables defined inside a batch file for an executable are still defined after the executable terminated itself. Therefore the environment variables are readable for any other executable started next by cmd.exe in same batch file or even after batch file processing finished depending on how cmd.exe was started for processing the batch file and the execution environment defined by the batch file itself.
The Windows command processor uses the Windows kernel library function CreateProcess to run an executable like any other Windows application capable running an executable. cmd.exe uses always NULL for the CreateProcess function parameter lpEnvironment which results in CreateProcess making a copy of the current environment variables list of cmd.exe for the executable started next.
The commands SETLOCAL and ENDLOCAL can be used in a batch file to define the environment variables evaluated by an executable just for the executable as the code below demonstrates.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem The two command lines above define completely the execution environment for the
rem batch file and so the batch file does not depend anymore on settings outside of
rem the batch file.
rem Define MyVariable1 and undefine MyVariable2
set "MyVariable1=Demo"
set "MyVariable2="
rem Verify that with an output of all environment variables of
rem which name starts with the string MyVariable with their values.
echo/
echo My variables defined in batch script at top:
echo/
set MyVariable
setlocal
set "MyVariable1=Other value for execuable"
set "MyVariable2=Defined also for executable"
echo/
echo My variables defined for mybinary:
echo/
set MyVariable
if exist mybinary mybinary
endlocal
echo/
echo My variables defined after execution of mybinary:
echo/
set MyVariable
endlocal
echo/
echo My variables as defined outside of the batch file:
echo/
set MyVariable
echo/
pause
I recommend to read this answer in addition to execution of setlocal /? and endlocal /? in a command prompt window to get full knowledge on what is done by these two commands in background.
4. Referencing files in batch file directory with full path
The Windows command processor cmd.exe can be executed for processing a batch file from within any directory which means the current working directory can be any directory. For that reason it is advisable to reference other files in the directory of the batch file with full path and with file extension instead of just the file name.
The usage of just mybinary results in searching in current working directory for a file with name mybinary having one of the file extensions as listed in environment variable PATHEXT if the environment variable NoDefaultCurrentDirectoryInExePath is not defined. In other words the successful execution of mybinary depends on execution environment settings defined outside of the batch file which is not good.
So it is advisable to use "%~dp0mybinary.exe" in the batch file to reference the executable with full qualified file name whereby %~dp0 references the drive and path (can be also a UNC path) of argument 0 which is the full folder path of the batch file always ending with a backslash and therefore concatenated without an additional backslash with file name mybinary.exe.
The usage of "%~dp0mybinary.exe" has following advantages regarding to execution of this executable:
It does not matter anymore how the environment variable PATHEXT is defined.
It does not matter anymore if the environment variable NoDefaultCurrentDirectoryInExePath is defined or not.
It does not matter anymore what is the current working directory on execution of the batch file as long as the executable is good coded and does not expect that the directory containing the executable is the working directory to access other files in that directory.
For completeness regarding usage of %~dp0 see also:
What is the reason for batch file path referenced with %~dp0 sometimes changes on changing directory?

Error: "is not recognized as an internal or external command, operable program or batch file"

Whenever I try and run mycommand.exe from my Windows cmd.exe terminal, I get this error:
''mycommand.exe' is not recognized as an internal or external command, operable program or batch file'
Secondly
I've also experienced a similar error when I tried to run C:\Program Files\My-App\Mobile.exe
''C:\Program' is not recognized as an internal or external command, operable program or batch file'
This is a very common question seen on Stackoverflow.
The important part here is not the command displayed in the error, but what the actual error tells you instead.
a Quick breakdown on why this error is received.
cmd.exe Being a terminal window relies on input and system Environment variables, in order to perform what you request it to do. it does NOT know the location of everything and it also does not know when to distinguish between commands or executable names which are separated by whitespace like space and tab or commands with whitespace as switch variables.
How do I fix this:
When Actual Command/executable fails
First we make sure, is the executable actually installed? If yes, continue with the rest, if not, install it first.
If you have any executable which you are attempting to run from cmd.exe then you need to tell cmd.exe where this file is located. There are 2 ways of doing this.
specify the full path to the file.
"C:\My_Files\mycommand.exe"
Add the location of the file to your environment Variables.
Goto:
------> Control Panel-> System-> Advanced System Settings->Environment Variables
In the System Variables Window, locate path and select edit
Now simply add your path to the end of the string, seperated by a semicolon ; as:
;C:\My_Files\
Save the changes and exit. You need to make sure that ANY cmd.exe windows you had open are then closed and re-opened to allow it to re-import the environment variables.
Now you should be able to run mycommand.exe from any path, within cmd.exe as the environment is aware of the path to it.
When C:\Program or Similar fails
This is a very simple error. Each string after a white space is seen as a different command in cmd.exe terminal, you simply have to enclose the entire path in double quotes in order for cmd.exe to see it as a single string, and not separate commands.
So to execute C:\Program Files\My-App\Mobile.exe simply run as:
"C:\Program Files\My-App\Mobile.exe"
When you want to run an executable file from the Command prompt, (cmd.exe), or a batch file, it will:
Search the current working directory for the executable file.
Search all locations specified in the %PATH% environment variable for the executable file.
If the file isn't found in either of those options you will need to either:
Specify the location of your executable.
Change the working directory to that which holds the executable.
Add the location to %PATH% by apending it, (recommended only with extreme caution).
You can see which locations are specified in %PATH% from the Command prompt, Echo %Path%.
Because of your reported error we can assume that Mobile.exe is not in the current directory or in a location specified within the %Path% variable, so you need to use 1., 2. or 3..
Examples for 1.
C:\directory_path_without_spaces\My-App\Mobile.exe
or:
"C:\directory path with spaces\My-App\Mobile.exe"
Alternatively you may try:
Start C:\directory_path_without_spaces\My-App\Mobile.exe
or
Start "" "C:\directory path with spaces\My-App\Mobile.exe"
Where "" is an empty title, (you can optionally add a string between those doublequotes).
Examples for 2.
CD /D C:\directory_path_without_spaces\My-App
Mobile.exe
or
CD /D "C:\directory path with spaces\My-App"
Mobile.exe
You could also use the /D option with Start to change the working directory for the executable to be run by the start command
Start /D C:\directory_path_without_spaces\My-App Mobile.exe
or
Start "" /D "C:\directory path with spaces\My-App" Mobile.exe
when you have this problem
search for Environment variables
press on Environment variables
Under "System varibles" you search for PATH and press edit
press on new and add the path of your program and save it

Batch How to start a program

I want to create a batch file to launch my executable file after it has made some changes to itself.
My batch file is:
START /D "C:\Users\me\AppData\Roaming\Test\Test.exe"
When I run it though I just get a brief console flash and Test.exe doesn't start up.
I've verified the EXE is there in the directory.
I've launched the exe manually to verify it is working as well.
My batch file resides in
C:\Users\admin\AppData\Roaming\run.bat"
There are two issues:
The /D option solely defines the starting or working directory, but not the program to execute.
The start command considers the first quoted argument as the title of the new window. To avoid confusion with other arguments, always provide a window title (that may also be empty).
There are two solutions, which are actually not exactly equivalent:
Remove the /D option, so the current working directory is used:
start "" "C:\Users\me\AppData\Roaming\Test\Test.exe"
Keep the /D option and explicitly provide the new working directory to be used:
start "" /D "C:\Users\me\AppData\Roaming\Test" "Test.exe"
try changing to this
start /d "C:\Users\me\AppData\Roaming\Test" Test.exe
You will see the console flash and your program should startup.
Update
Thanks for #SomethingDark 's suggestion to use the following code.
start "" C:\Users\me\AppData\Roaming\Test\Test.exe
However, the above code will not work if your filename contains space.
Try with the following command.Add it to your batch script.Notice that you have to add double quotes after start keyword if there is/are whitespaces in the path string.
start "" "C:\Users\me\AppData\Roaming\Test\Test.exe"
Enclose any directory names which are longer than one-word into quotation marks. So the following path:
start C:\Program Files\MySQL\MySQL Workbench 8.0 CE\MySQL.exe
Should become something like this:
start C:\"Program Files"\MySQL\"MySQL Workbench 8.0 CE"\MySQL.exe

Batch File To Get It's Own Directory Or The Directory Defined In The "Start In" Property Of A Shortcut

I am writing a batch file on my Windows 8.1 machine. In one section of my batch file I need to start a command prompt in the "current working directory".
So far, this is what my batch file looks like:
#echo OFF
set WORKING=%cwd%
start cmd.exe /K pushd %WORKING%
exit
Let's say the batch file is located in the folder C:\Temp\Utilities. If I open an explorer window and double click the batch file to run it everything works great. A new command prompt is created in the directory C:\Temp\Utilities. However, if I right-click the batch file and select Run as administrator the working directory is no longer the location of the batch file, it's C:\Windows\System32.
Similarly, if I create a shortcut to the batch file in a different folder (for example. C:\Temp) and repeat the two steps above the results are the same. If I double click the shortcut and run it as a normal user the working directory is what I would expect. (Note, the working directory for the shortcut it's whatever is set for "Start in" of the shortcut properties, not the location of the batch file.) If I right click the shortcut and run it as administrator I again get a command prompt opened to the folder C:\Windows\System32.
I assume this is a "bug" or "feature" (if you want to call it that) in Windows 8.1 and it probably happens because execution environments for programs run as administrator are forced to run in the System32 folder? (I remember with Windows 7 this did not happen so it must be a new feature to Windows 8.)
I found one way to fix the issue and stop the command prompt from starting in C:\Windows\System32. I did this by modifying the following line in the batch file:
set WORKING=%~dp0
Doing it this way sets the working directory to the location of the batch file. With this change, no matter how I run the batch file or the shortcut (administrator or normal) the working directory ends up being the same, C:\Temp\Utilities.
The problem with this solution is I don't want the working directory to always be the location of the batch file. If the batch file is run directly then it's okay but if I run it from a shortcut I need the working directory to be whatever is set in the "Start in" property of that shortcut. For example, if the batch file is located in the folder D:\Temp\Utilities this is what I need to happen regardless of whether I run as administrator or not:
Shortcut Location Start In Property Command Prompt Working Directory
-------------------- ------------------- ------------------------------------------
C:\Temp <undefined> D:\Temp\Utilities
C:\Data\bin C:\Data\bin C:\Data\bin
C:\Data\bin D:\Temp\Utilities D:\Temp\Utilities
What this means is I can't always use %~dp0 to set the working directory in my batch file. What I need is some way for the batch file to know if it was run either directly or by a shortcut. If the batch file is run directly then the working directory is easy to get, it's just the value of %cwd%. If the batch file is run by using a shortcut, I don't know how to get the "Start in" property inside the batch file.
Does anyone know how I can do these two things inside my batch file:
1. Check whether it was run directly or by a shortcut.
2. If run by a shortcut, get the "Start in" property of the shortcut that started it.
Thank you,
Orangu
UPDATE
I found sort-of a "hackish" way to fix the issue. For the shortcut I edited the "Target" field and changed it to the following:
cmd.exe /k pushd "C:\Temp" && "D:\Temp\Utilities\batchfile.bat"
Now the working directory can be obtained by calling %CD% in the batch file and this works for both administrator and normal users. It does not, however, work for the case when I run the batch file directly. I still need to use %~dp0 in that case.
I don't like this solution, however, because it requires me to manually change all shortcuts I make and it also makes the icon look like a cmd prompt icon rather than a batch file.
Have you already considered to not use shortcuts at all?
You could e.g. create a batchfile_exec.bat containing your call
REM optionally do
REM cd /D working_directory
REM if you want to force a special working directory
D:\Temp\Utilities\batchfile.bat
and replace all the shortcuts with batchfile_exec.bat. If you double-click batchfile_exec.bat, the working directory will be the one containing batchfile_exec.bat.
I personally don't like Windows shortcuts that much, because they are hard to handle within a revision control system. As you also noticed, it is very time consuming if you want to modify a lot of them.
By the way: If batchfile.bat was designed/written to be always run from the direcory where it is located, you might also consider to modify batchfile.bat to force that behaviour:
setlocal
cd /D %0\..
REM your original content
endlocal
In %0 the path to the batchfile is stored.
The trick is to assume that %0 is a directory and then to change one level lower based on that directory. With /D also the drive letter is changed correctly.
The cd command doesn't care if %0 is really a directory. In fact %d doesn't even have to exist (%0\dummy\..\.. would also work).
The setlocal command is to have the working directory being restored when batchfile.bat has finished (this would be good if batchfile.bat was called form another batch file).
I noticed that the endlocal command is not really necessary in this context since it is applied implicitly when batchfile.bat finishes.

Resources