Pass multiple variables to binary - batch-file

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?

Related

Starting batch file using QProcess.execute() on different Windows version

I'm new to QT and have been spending a lot of time on this issue now.
Starting a batch file like below on Windows 10 has no problem but fails at Windows 7 and Windows XP.
Qprocess process;
QString data = "test.bat";
int success = 0;
success=process.execute(data);
The above snippet works fine on Windows 10.
On Windows 7 and XP it works if the data is modified as below:
"cmd.exe /c start test.bat"
Why does this difference exist for different Windows version ?
Help much appreciated!!
The question cannot be really answered as the used code depends on the execution environment defined outside of the application by the parent process on starting the application and there is nothing posted how the application is started on Windows XP, Windows 7 and Windows 10.
test.bat is referenced with no path which means it must be found in the current directory set for the application coded in C++ using Qt5 by the parent process on execution of the Windows library function CreateProcess which is used also by Qt5 class QProcess on Windows.
A batch file is not an executable. It is a script file which needs a script interpreter which is for batch files since Windows NT4 the Windows command processor cmd.exe. So the Windows command processor must be executed to process the batch file which is most likely stored in the directory of the C++ coded application using Qt5.
It is highly recommended to write the C++ code with using Qt5 being independent on the current working directory of the application and the environment variables PATH and PATHEXT by using the following commented code.
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QProcess>
int main(int argc, char **argv)
{
QCoreApplication qDemoApp(argc,argv);
// Get the fully qualified file name of the Windows command processor.
QString qsCmdFileName = qEnvironmentVariable("ComSpec");
// The environment variable ComSpec is usually defined on Windows
// as system environment variable, but check if really existing.
if(qsCmdFileName.isEmpty())
{
// Get the full path to the Windows directory not ending with the
// directory separator using the environment variable SystemRoot.
qsCmdFileName = qEnvironmentVariable("SystemRoot");
// It is very unlikely that this environment variable is not defined
// as it is always defined by the Windows shell, i.e. explorer.exe
// running as Windows shell. But it is nevertheless possible that
// the environment variable is not defined in the list of the
// environment variables of the current process. In this case use
// directory Windows on system drive as directory and hope this
// directory exists as otherwise the execution of cmd.exe fails.
if(qsCmdFileName.isEmpty())
{
qsCmdFileName = QDir::toNativeSeparators(QDir::rootPath()) + QStringLiteral("Windows");
}
qsCmdFileName.push_back(QStringLiteral("\\System32\\cmd.exe"));
}
// The process must be executed with the following command line on
// C:\Windows\System32\cmd.exe is the fully qualified file name of
// the Windows command processor and the application directory has
// the unusual path C:\Temp\Development & Test(!) containing the
// batch file Test.bat which is explicitly set as working directory.
// C:\Windows\System32\cmd.exe /D /E:ON /V:OFF /C Test.bat
QStringList lqsArgumentsList(QStringLiteral("/D"));
lqsArgumentsList.append(QStringLiteral("/E:ON"));
lqsArgumentsList.append(QStringLiteral("/V:OFF"));
lqsArgumentsList.append(QStringLiteral("/C"));
lqsArgumentsList.append(QStringLiteral("Test.bat"));
QProcess qWindowsCommandProcess;
qWindowsCommandProcess.setWorkingDirectory(QCoreApplication::applicationDirPath());
qWindowsCommandProcess.start(qsCmdFileName,lqsArgumentsList,QIODevice::NotOpen);
if(!qWindowsCommandProcess.waitForFinished(-1))
{
QChar qSpace(' ');
QString qsCommandLine = qsCmdFileName + qSpace;
qsCommandLine.push_back(lqsArgumentsList.join(qSpace));
qInfo().noquote().nospace() << "ERROR: Failed to execute\n" << qsCommandLine << "\nin the directory:\n\""
<< QDir::toNativeSeparators(QCoreApplication::applicationDirPath()) << QChar('\"');
return 1;
}
return 0;
}
The Windows command processor arguments /E:ON and /V:OFF can be removed if the batch file Test.bat contains at top
#echo off
setlocal EnableExtensions DisableDelayedExpansion
and has as last line
endlocal
to define the execution environment completely without depending on which environment is defined on starting cmd.exe respectively on Windows command processor defaults which Windows users could customize although usually not done by them as most batch files would not work anymore as expected by their authors on really doing that. Run in a command prompt window cmd /? for the usage help and read the Microsoft documentation about cmd for more details.
Good coded applications do not depend on execution environment properties defined outside of the application as much as possible. The code above depends on the environment variable ComSpec and if not defined on environment variable SystemRoot. The usage of these two environment variables could be also avoided, but that would require the usage of the native Windows library function GetSystemDirectory instead of Qt5 functions.
For testing this code create in application directory the batch file Test.bat with the single command line #echo Executed %0 at %TIME% in "%CD%">"%~n0.txt". Then create another batch file AppTest.bat with the following command lines with environment variable AppPath defined with correct path to the directory containing your executable and Test.bat and AppName defined correct with file name plus file extension of your application:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "AppPath=C:\Full Path\To Application"
set "AppName=AppName.exe"
rem Set a directory different to application directory as current directory.
cd /D "%TEMP%"
call :TestRun "Use environment variable ComSpec defined with: %ComSpec%"
set "ComSpec=C:\Temp\cmd.exe"
call :TestRun "Use environment variable ComSpec defined with: %ComSpec%"
set "ComSpec="
call :TestRun "Use environment variable SystemRoot defined with: %SystemRoot%"
set "SystemRoot=C:\Temp"
call :TestRun "Use environment variable SystemRoot defined with: %SystemRoot%"
set "SystemRoot="
call :TestRun "Use environment variable SystemDrive defined with: %SystemDrive%"
set "SystemDrive=Z:"
call :TestRun "Use environment variable SystemDrive defined with: %SystemDrive%"
set "SystemDrive="
call :TestRun "Use environment variable SystemDrive not defined at all."
goto EndBatch
:TestRun
echo %~1
"%AppPath%\%AppName%"
if not errorlevel 1 if exist "%AppPath%\Test.txt" (
type "%AppPath%\Test.txt"
del "%AppPath%\Test.txt"
)
echo/
goto :EOF
:EndBatch
pause
endlocal
QDir::rootPath() makes use of the Windows system environment variable SystemDrive on being compiled without preprocessor macro Q_OS_WINRT defined.
The batch file AppTest.bat can be executed from within a command prompt window or with a double click on it in Windows File Explorer.

Why does my VBScript function differently if it is opened by a batch script rather than a person?

Simply put, I have a VBScript titled "tyrian_soundtest.vbs" that plays an .mp3 that is titled "tyrian_soundtest.mp3"
The VBScript code is below
Set Sound = CreateObject("WMPlayer.OCX.7")
Sound.URL = "tyrian_soundtest.mp3"
Sound.Controls.play
do while Sound.currentmedia.duration = 0
wscript.sleep 1
loop
wscript.sleep (int(Sound.currentmedia.duration)+1)*1000
When opened, it plays the .mp3. Simple enough.
The trouble comes in when I run a batch script titled "tyrian_soundtest.bat". Relative to it, the .vbs and .mp3 are in a folder called sfx. Here is what one iteration of that file contained.
#echo off
start %cd%\sfx\tyrian_soundtest.vbs
exit /b
The result is an error stating that Windows couldn't find the file path, likely due to it containing a space. Other attempts of the .bat were replacing line 2 with
start .\sfx\tyrian_soundtest.vbs
or
start "%cd%\sfx\tyrian_soundtest.vbs"
Any attempt I've made gives one of three results. Option 1: There is no error, but the audio simply never plays. Option 2: An error is thrown about the file directory not being found. Option 3: That file path opens up in a new cmd window, but the .vbs is never run.
Is there any way format the .bat to get the .vbs to run through the without an error being caused?
The main issue is that there is used in batch file and in the VBScript file the current directory path. The current directory on starting %SystemRoot%\System32\cmd.exe to process the batch file can be any directory.
The Windows Explorer sets the directory of the batch file as current directory on double clicking the batch file resulting in starting cmd.exe by explorer.exe to process the double clicked batch file of which full qualified file name is passed to cmd.exe after the option /c as additional argument. But if the batch file is stored on a network resource accessed using UNC path, the Windows command processor changes the current directory from the network resource to %SystemRoot% (the Windows directory) and the batch file fails to start Windows Script Host to process the VBS file. See also: CMD does not support UNC paths as current directories.
A batch file can be also started by right clicking on it and using Run as administrator. This can result in making the directory %SystemRoot%\System32 (the Windows system directory) the current directory. See also: Why does 'Run as administrator' change (sometimes) batch file's current directory?
That are just two of many examples where the current directory is different to the directory containing the batch file. So if a batch file references other files stored in same directory as the batch file itself or a subdirectory of the batch files directory, it is advisable to reference these files with the full path of the batch file instead of using a path relative to current directory.
Example:
The used files are stored in directory C:\Temp\Development & Test as follows:
sfx
tyrian_soundtest.vbs
tyrian_soundtest.mp3
tyrian_soundtest.bat
A user opens a command prompt window which usually results in making the directory referenced with %USERPROFILE% or with %HOMEDRIVE%%HOMEPATH% the current directory. A user executes next in the command prompt window:
"C:\Temp\Development & Test\tyrian_soundtest.bat"
So the current directory is definitely not the directory containing the batch file.
The batch file can be coded as follows to start nevertheless the Windows Script Host for processing the VBS file tyrian_soundtest.vbs and successfully play the MP3 file tyrian_soundtest.mp3.
#start "" /D "%~dp0sfx" %SystemRoot%\System32\wscript.exe //NoLogo "%~dp0sfx\tyrian_soundtest.vbs"
%~dp0 references the drive and path of argument 0 which is the full path of the currently processed batch file. The batch file path referenced with %~dp0 always ends with a backslash. For that reason the concatenation of %~dp0 with a file/folder name or wildcard pattern should be always done without using an additional backslash as that would result in two \ in series in complete argument string and the Windows file management would need to fix that small error by replacing \\ by just \ before passing the argument string to the file system. See also the Microsoft documentation about Naming Files, Paths, and Namespaces which explains which automatic corrections are usually applied on file/folder strings before passing them to the file system.
The internal command START of cmd.exe interprets the first double quoted argument string as title string for the console window as it can be seen on running in a command prompt window start /? and reading the output help. For that reason it is not enough to use just:
#start "%~dp0sfx\tyrian_soundtest.vbs"
That would result in starting one more command process with its own console window with the full qualified file name of the VBS file as title of the console window.
The Windows Script Host processing a VBS file by default on Windows exists in two versions:
%SystemRoot%\System32\cscript.exe is the console version.
%SystemRoot%\System32\wscript.exe is the Windows GUI version.
The usage of the console version cscript.exe results usually in opening a console window by the parent process if the parent process is not itself a console application running already with an opened console window like on execution of a batch file processed by %SystemRoot%\System32\cmd.exe being also a console application.
The usage of the Windows GUI version wscript.exe results in no opening of a window by default at all. The processed script file must contain commands to open a window if that is wanted at all.
The difference can be also seen on running from within a command prompt window cscript /? and next wscript /?. The first command results in printing the help for the command line options of Windows Script Host in already opened command prompt window while the second command results in showing a graphic window by wscript.exe displaying the same usage help.
The usage help of Windows Script Host explains also how each user can define which version of Windows Script Host is the default for executing scripts. So it is not advisable to specify just the VBS file name with full path on the command line with start and let cmd.exe look up in Windows registry which version of Windows Script Host to run to process the VBS file. It is better to explicitly run the version of Windows Script Host most suitable for playing the MP3 file which is in this case the Windows GUI version wscript.exe opening by default no window at all to play the MP3 file in background.
So it would be possible to use:
#start "" %SystemRoot%\System32\wscript.exe //NoLogo "%~dp0sfx\tyrian_soundtest.vbs"
There is an empty title string defined with "" as the started executable wscript.exe is a Windows GUI application for which no console window is opened at all by cmd.exe. So the title string does not really matter and can be an empty string.
But there is left one problem with that command line. The VB script references the MP3 file without path which means with a path relative to current directory. The current directory is %USERPROFILE% and not C:\Temp\Development & Test\sfx which contains the MP3 file tyrian_soundtest.mp3. So the VB script would fail to find the MP3 file to play.
There are two solutions to fix this:
The usage of the following command line in the batch file:
#start "" /D "%~dp0sfx" %SystemRoot%\System32\wscript.exe //NoLogo "%~dp0sfx\tyrian_soundtest.vbs"
The option /D of command START is used to explicitly set the subdirectory sfx of the batch file directory as start in respectively current directory for the process wscript.exe which cmd.exe starts using the Windows kernel library function CreateProcess with an appropriate created structure STARTUPINFO.
The VBS file references the MP3 file tyrian_soundtest.mp3 with its full path which the VB script file determines itself from its own full qualified file name. That can be achieved in the VB script file tyrian_soundtest.vbs by using in the second line:
Sound.URL = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) + "\tyrian_soundtest.mp3"
Best would be using both possible solutions as in this case the VB script file would work also on being executed by a different process than cmd.exe processing the batch file tyrian_soundtest.bat and deletion of directory %~dp0sfx is not possible as long as started wscript.exe is running because of this directory is the current directory of running Windows Script Host.
So the batch file as well as the VB script file work now both independent on which directory is the current directory as both reference the files with full path determined by the scripts themselves from their full qualified file names.

How to use a Batch file to set PATH and then input commands normally?

I'm setting up an external hard drive with portable apps, and there are some CLI tools that I'd like to easily access.
I've done it before but I forgot how; basically, I have a file which sets the PATH variable for all the required CLI programs, and then allows me to use the command prompt normally.
How do I do this without having to run the file from another command prompt, but by double clicking the Batch file?
If your command line tools are in a folder named CLiTools next to the batch-file, then you could have 2 lines as the batch-file content.
#set "path=%path%;%~dp0CLiTools"
#cmd
You can double click the batch-file, it will open cmd with the modified setting of %path% and you can enter commands as you would normally do. If you have i.e. xyz.exe in the CLiTools folder, then you can type xyz at the current command prompt and will be recognized as a command.
The changed environment applies to the current child cmd session that inherited the environment.
%~dp0 is the drive and path of argument 0 which is the drive and path to the batch-file in this case.

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

Iterating over files in directory prepends extra character to filename

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.

Resources