Search code examples
cmd

How to properly pass full file names to `cmd /c`?


I am trying to run a command in CMD prompt to get information from my SVN (TortoiseSVN 1.7.8). In a cmd prompt, I enter:

cmd /c C:\Program Files\TortoiseSVN\bin\svn.exe info C:\MyCode\CurrProj\Ry1

I get:

'C:\Program' is not recognized as an internal or external command, operable program or batch file.

That makes sense as there is a space after 'C:\Program'. Ok, so if I enter:

cmd /c "C:\Program Files\TortoiseSVN\bin\svn.exe" info C:\MyCode\CurrProj\Ry1

then all works as expected. However, if the location (the last path) contains spaces:

cmd /c "C:\Program Files\TortoiseSVN\bin\svn.exe" info C:\MyCode\Curr Proj\Ry1

I get:

svn: E155007: 'C:\MyCode\Curr' is not a working copy

So this means that the SVN command ran and used only part of the code location. So I added quotes around that path too:

cmd /c "C:\Program Files\TortoiseSVN\bin\svn.exe" info "C:\MyCode\Curr Proj\Ry1"

Which brings me back to error message:

'C:\Program' is not recognized as an internal or external command, operable program or batch file.

WHAT?? Can someone explain why the CMD prompt is not interpreting this correctly? Shouldn't the last example launch a CMD prompt with the 'Close' option and run:

"C:\Program Files\TortoiseSVN\bin\svn.exe" info "C:\MyCode\Curr Proj\Ry1"

If i run: "C:\Program Files\TortoiseSVN\bin\svn.exe" info "C:\MyCode\Curr Proj\Ry1" by itself, it works as expected, but this command will be run in a process that is created programatically in some C# code:

System.Diagnostics.ProcessStartInfo procStartInfo =
                new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

where command = "C:\Program Files\TortoiseSVN\bin\svn.exe" info "C:\MyCode\Curr Proj\Ry1"


Solution

  • Excerpt from cmd /help:

    If /C or /K is specified, then the remainder of the command line after
    the switch is processed as a command line, where the following logic is
    used to process quote (") characters:
    
        1.  If all of the following conditions are met, then quote characters
            on the command line are preserved:
    
            - no /S switch
            - exactly two quote characters
            - no special characters between the two quote characters,
              where special is one of: &<>()@^|
            - there are one or more whitespace characters between the
              two quote characters
            - the string between the two quote characters is the name
              of an executable file.
    
        2.  Otherwise, old behavior is to see if the first character is
            a quote character and if so, strip the leading character and
            remove the last quote character on the command line, preserving
            any text after the last quote character.