Question

Working with "C:\Program Files (x86)" I ran into a strange issue with a program located somewhere below that path. I reproduced the behaviour with a test program.

    int _tmain(int argc, _TCHAR* argv[])
{
    wprintf(L"%d\n", argc);
    for (int i = 0; i < argc; i++) {
        wprintf(L"%s\n", argv[i]);
    }
    return 0;
}

The program counts and returns all command line arguments (including the path to program used to identify the program). I named it "HelloWorld.exe" because I was in a hurry.

For three possible ways to run the program it gives two different results, whereas I was expecting the same result.

When I run HelloWorld.exe from its own directory, the output is

1
HelloWorld.exe

That output is correct and expected.

When I run HelloWorld.exe, which is located in "P:\Test (x86)", from another location and use the quoted path, the output is

1
P:\Test (x86)\HelloWorld.exe

That output is also correct and expected.

However, when I run HelloWorld.exe from another location and use a path with escaped spaces and brackets, the program is found (i.e. the path is correct), but the output is wrong:

2
P:\Test
(x86)\HelloWorld.exe

For some reason the escaped space in

P:\Test\^ ^(x86^)\HelloWorld.exe

becomes a space-read-as-operator for some reason and Windows, after reading the path as one string to find the program, decides that it is really two strings after all before creating that array the program then refers to.

This behaviour occurs in both Windows XP (x86) and Windows Server 2008 R2 (x64). I assume it is present in all (NT) versions of Windows.

Was it helpful?

Solution

Update:

Oops. Maybe it is a bug (or perhaps the term is misfeature) in Windows.

I just made a quick little test program that simply calls GetCommandLine() and prints that out to the console.

I called it with:

test The^ rain^ in^ Spain^ falls^ mainly^ on^ the^ plain^ ^(or^ so^ they^ say^).

And this is the output:

test  The rain in Spain falls mainly on the plain (or so they say).

So I guess the runtime library never sees the carets at all, and your only option is to tell your users to use quotes instead of escapes.


No, it's not a bug in Windows. It's a bug (although I might prefer the term shortcoming or deficiency in this case) in your C runtime library.

Windows is processing the escape characters and locating your executable. But it's not what separates the command line into arguments. Windows is not what calls your main function (or _tmain in this case). It simply starts your process at the entry point defined within the PE header. At this location is some C library code (or a dynamic call into it) that, among other startup tasks, calls the kernel32 function GetCommandLine(), then splits that on spaces, honoring quotes, but not, apparently, caret escapes.

It's not very surprising, really. I don't think most people know that you can escape characters with carets on the Windows command line. I certainly didn't.

If this is causing a real-world issue for you, where somebody is actually using caret escapes to invoke your program, you can either tell them to stop, or write your own command-line parsing routine, passing to it the output of GetCommandLine(), and ignore what you get passed to you in main.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top