Invalid syntax with "setx" for having more than two arguments when there are only two arguments

octopod picture octopod · Mar 22, 2015 · Viewed 16.2k times · Source

I'm having trouble setting the global environment variable PATH permanently with SETX.

I've read the answers on similar questions such as Invalid syntax with setx as well as read the syntax on SS64.

As far as I know, the following line follows the syntax of SETX correctly and does NOT have more than two arguments in it:

SETX PATH "%PATH%"

But that doesn't stop SETX from giving me this error:

ERROR: Invalid syntax. Default option is not allowed more than '2' time(s).
Type "SETX /?" for usage.

The above command was run on an administrator instance of cmd.exe. What makes the problem all the more stranger is that on a user instance of cmd.exe the same command works perfectly.

I simplified the above command to emphasize the problem, but what I'm really trying to run is:

SETX PATH "%PATH%;D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin" /M

Of course, this gives the same exact error, and I can't run it on a user instance of cmd.exe because I'm trying to set the global environment variable PATH permenantly. (which needs administrator access)

Answer

JosefZ picture JosefZ · Mar 22, 2015
 echo %PATH%

If your (machine level) %path% ends with a trailing \ reverse solidus (backslash), you should double it as follows:

if "%path:~-1%"=="\" (
   SETX PATH "%PATH%\"
) else (
   SETX PATH "%PATH%"
)

Resource: Syntax : Escape Characters, Delimiters and Quotes (note my own highlights in following citation):

Some commands (e.g. REG and FINDSTR) use the standard escape character of \ (as used by C, Python, SQL, bash and many other languages.) The \ escape can cause problems with quoted directory paths that contain a trailing backslash because the closing quote " at the end of the line will be escaped \".

To save a directory path with a trailing backslash (\) requires adding a second backslash to 'escape the escape' so for example instead of "C:\My Docs\" use "C:\My Docs\\"

Above statements on trailing \ applies to SETX as well. Here's an example:

==>set myPath
myPath=D:\Program Files\OgreSDK\

==>setx myOgre "%myPath%"
SUCCESS: Specified value was saved.

==>reg query HKEY_CURRENT_USER\Environment /v myOgre
HKEY_CURRENT_USER\Environment
    myOgre    REG_SZ    D:\Program Files\OgreSDK"

==>setx myOgre "%myPath%\"
SUCCESS: Specified value was saved.

==>reg query HKEY_CURRENT_USER\Environment /v myOgre
HKEY_CURRENT_USER\Environment
    myOgre    REG_SZ    D:\Program Files\OgreSDK\

==>

The Invalid syntax error relates to broken user level %PATH% variable caused by first using of SETX PATH "%PATH%" as user level environment variable takes precedence over machine level one. To solve the problem, adjust user level %PATH% variable (or remove it at all) first via Windows GUI (preferred):

Control Panel | System | Advanced | Environment Variables

Proof - reproduce the problem in two steps:

Step #1: start with good %myPath% variable on machine level with trailing \; lastly (in fine) broke this variable for current user level and exit the cmd session.

==>set myPath
myPath=D:\temp\foo foo\

==>reg query HKEY_CURRENT_USER\Environment /v myPath
ERROR: The system was unable to find the specified registry key or value.

==>reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"  /v myPath
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    myPath    REG_SZ    D:\temp\foo foo\

==>setx myPath "%myPath%;D:\temp\bu bu bu"
SUCCESS: Specified value was saved.

==>reg query HKEY_CURRENT_USER\Environment /v myPath
HKEY_CURRENT_USER\Environment
    myPath    REG_SZ    D:\temp\foo foo\;D:\temp\bu bu bu

==>rem fetch erroneous state
==>setx myPath "%myPath%"
SUCCESS: Specified value was saved.

==>reg query HKEY_CURRENT_USER\Environment /v myPath
HKEY_CURRENT_USER\Environment
    myPath    REG_SZ    D:\temp\foo foo"

==>exit

Step #2: in a new cmd session, start with broken %myPath% variable on user level with trailing "; this raises the error described in question.

==>set myPath
myPath=D:\temp\foo foo"

==>reg query HKEY_CURRENT_USER\Environment /v myPath
HKEY_CURRENT_USER\Environment
    myPath    REG_SZ    D:\temp\foo foo"

==>reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"  /v myPath
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
    myPath    REG_SZ    D:\temp\foo foo\

==>setx myPath "%myPath%;D:\temp\bu bu bu"
ERROR: Invalid syntax. Default option is not allowed more than '2' time(s).
Type "SETX /?" for usage.

==>reg query HKEY_CURRENT_USER\Environment /v myPath
HKEY_CURRENT_USER\Environment
    myPath    REG_SZ    D:\temp\foo foo"

==>