Spaces and Parenthesis in windows PATH variable screws up batch files

So, my path variable (System->Adv Settings->Env Vars->System->PATH) is set to:

C:\Python26\Lib\site-packages\PyQt4\bin;
%SystemRoot%\system32;
%SystemRoot%;
%SystemRoot%\System32\Wbem;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;
C:\Python26\;
C:\Python26\Scripts\;
C:\cygwin\bin;
"C:\PathWithSpaces\What_is_this_bullshit";
"C:\PathWithSpaces 1.5\What_is_this_bullshit_1.5";
"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";
"C:\Program Files (x86)\IronPython 2.6";
"C:\Program Files (x86)\Subversion\bin";
"C:\Program Files (x86)\Git\cmd";
"C:\Program Files (x86)\PuTTY";
"C:\Program Files (x86)\Mercurial";
Z:\droid\android-sdk-windows\tools;

Although, obviously, without the newlines.

Notice the lines containing PathWithSpaces - the first has no spaces, the second has a space, and the third has a space followed by a parenthesis.

Now, notice the output of this batch file:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\>vcvars32.bat
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>"C:\Program Files (x86
)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>      set "PATH=C:\Pro
gram Files\Microsoft SDKs\Windows\v6.0A\bin;C:\Python26\Lib\site-packages\PyQt4\
bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\
WindowsPowerShell\v1.0\;C:\Python26\;C:\Python26\Scripts\;C:\cygwin\bin;"C:\Path
WithSpaces\What_is_this_bullshit";"C:\PathWithSpaces 1.5\What_is_this_bullshit_1
.5";"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";"C:\Program Files (x86)\
IronPython 2.6";"C:\Program Files (x86)\Subversion\bin";"C:\Program Files (x86)\
Git\cmd";"C:\Program Files (x86)\PuTTY";"C:\Program Files (x86)\Mercurial";Z:\dr
oid\android-sdk-windows\tools;"

or specifically the line:

\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.

So, what is this bullshit?

Specifically:

  • Directory in path that is properly escaped with quotes, but with no spaces = fine
  • Directory in path that is properly escaped with quotes, and has spaces but no parenthesis = fine
  • Directory in path that is properly escaped with quotes, and has spaces and has a parenthesis = ERROR

Whats going on here? How can I fix this? I'll probably resort to a junction point to let my tools still work as workaround, but if you have any insight into this, please let me know :)


This can happen if there are unescaped parentheses in a line inside a "block" (which also uses parentheses for delimiting).

You can usually fix it by turning on delayed expansion and use variables with !var! instead of %var%. There isn't much more advice I could give without seeing the code.


Note for Windows users on 64-bit systems

Progra~1 = 'Program Files' Progra~2 = 'Program Files(x86)'

https://confluence.atlassian.com/display/DOC/Setting+the+JAVA_HOME+Variable+in+Windows


There should either (a) not be any quotes in the MS-Windows PATH environmental variable (PATH command) or (b) there should be quotes surrounding the entire expression following the (SET command). Unfortunately, this is not very well documented by MS, although they do state that if quotes are used, they will be included in the value of the variable (Windows XP Command Line Reference).

$ SET BLAH="blah blah(1)"
$ ECHO %BLAH%
"blah blah(1)"
$ SET BLAH=blah blah(1)
$ ECHO %BLAH%
blah blah(1)

This can cause problems that are inconsistent and therefore difficult to diagnose. For example if your path includes "C:\Python27", your machine will say "'python' is not recognized as an internal or external command, operable program or batch file." when you try to execute python. However some libraries may still be available.

You do not need to "escape" spaces or parentheses. If you need to escape special characters, then put quotes around the entire expression, including the variable name.

SET "PATH=%PATH%;C:\Program Files (x86)\path with special characters"

or you can use parentheses too.

(SET VAR=can't contain ampersand, parentheses, pipe, gt or lt)

Note, double quotes must come in pairs.

(SET VAR=illegal characters!@#$%^*_-+={}[]\:;""',./?)
echo %VAR%
illegal characters!@#$%*_-+={}[]\:;""',./?

However, there probably are not any characters that are valid pathnames, that would cause a problem with the SET command.


Microsoft documents the problem in "Error running command shell scripts that include parentheses".

The solution they suggest is to use delayed expansion.

SETLOCAL ENABLEDELAYEDEXPANSION
SET VAR=string containing ( and ) ...
IF "y" == "y" (
    ECHO !VAR! %VAR%
)
ENDLOCAL

For setting a path in an if block, rather than using SET PATH=, you should probably use the PATH command.

SET AddToPath=C:\Program Files (x86)\Whatever

SETLOCAL ENABLEDELAYEDEXPANSION
IF "%X%" == "%Y%" (
    ECHO Adding !AddToPath! to path !PATH!
    PATH !AddToPath!;!PATH!
)

For other variables, another solution may be to use quotes, but around the whole thing:

SET "MyVar=C:\Program Files (x86)\Whatever"