I can't add this as comment and therefore post it as answer.
The third argument of command dir
is path+file specification. Therefore the entire argument should be surrounded by double quotes and not just the path.
It is right that the value of an environment variable is a string which can contain already double quotes. When using this environment variable anywhere inside an argument of a command, it happens inevitably that the double quotes are now inside the argument string.
The startup code of most compilers handle this case now correct by removing the double quotes within the argument. But the correct behavior would be that the batch file removes the double quotes from the environment variable string first before using the environment variable inside an argument and instead put the entire argument into double quotes.
Parsing C command-line arguments explains the command line parser of applications created with Microsoft Visual C/C++ and no customized startup code is used. Unfortunately there is no description what happens with not escaped double quotes inside an argument string.
As I once wanted to know what is passed by the operating system to an application and how the application parses the command line, I wrote a little C code, compiled it with various compilers and ran some tests with those console applications on various Windows versions.
Here is the code of this little console application:
#include <stdio.h> // for printf()
#include <conio.h> // for getch()
int main (int argc, char *argv[])
{
int iNumber;
char sSpace[2] = " ";
printf("The arguments of the program are:\n\n");
if(argc < 10) *sSpace = '\0';
for(iNumber = 0; iNumber < argc; iNumber++)
{
printf("Argument %s%d: %s\n",iNumber < 10 ? sSpace : "",iNumber,argv[iNumber]);
}
printf("\nPress any key to exit ...");
getch();
printf("\n\n");
return(0);
}
I was most interested on my tests in argument 0 - the name of the application as I wanted to know if it can be used directly to get name of an INI file. This is not possible!
I compiled this little code with a very old Turbo C compiler producing a 16-bit DOS application, with an old version of DJGPP resulting in a 32-bit console application with a 16-bit executable header and with Visual C producing a real 32-bit console application.
The compiled console application has the name ArgCheck.exe
and is located in C:\Temp
which is the current working directory in a command prompt window opened on Windows XP SP3 x86.
The command line used was: ArgCheck.exe "%WINDIR%"\*.exe
The output of ArgCheck.exe
compiled with Visual C:
Argument 0: C:\Temp\ArgCheck.exe
Argument 1: C:\WINDOWS\*.txt
The output of ArgCheck.exe
compiled with old version of DJGPP:
Argument 0: C:\TEMP\ARGCHECK.EXE
Argument 1: C:\WINDOWS\*.txt
The output of ArgCheck.exe
compiled with very old Turbo C:
Argument 0: C:\TEMP\ARGCHECK.EXE
Argument 1: C:\WINDOWS
Argument 2: \*.txt
As it can be seen, the startup code of Turbo C omits also the double quotes, but the double quote within the argument was interpreted as end of an argument resulting in two additional arguments instead of just one after argument 0 which always exists. The string of argument 0 depends on how the executable was started by another process. In worst case it is just the file name without path and without file extension with wrong case of the letters.
Conclusion:
It should be always tested how the startup code of an application parses the command line arguments if double quotes exist anywhere within an argument instead of only at beginning and at end of an argument string.