2

I'm writing a batch script to edit my PATH variable. Some of my Path consists of variables. Like so: %JAVA_HOME%/bin. In side my batch script I do the following:

FOR %%A IN ("%PATH:;=";"%") DO ECHO %%A | FINDSTR /I /C:%stringToFind% >NUL && SET found=true || SET newPath=!newPath!;%%A

So, the %newPath% variable will contain all the paths I want to keep.

Which is fine, except when I save my newPath to %PATH% using SETX. All my variables are expanded. So, instead of %JAVA_HOME%/bin; I get C:\PROGRA~1\Java\jdk1.8.0_25\bin;

My question is how do I keep my variables in my path as variables. How do I get the paths without expanding the variables. Keep them as: %whatever%. I Googled to no avail. Any help greatly appreciated.

user1543871
  • 355
  • 1
  • 6
  • 16
  • possible duplicate of [how to escape % at cmd setx?](http://stackoverflow.com/questions/6399768/how-to-escape-at-cmd-setx) – famousgarkin Feb 01 '15 at 19:42
  • 1
    I seen this post. My problem is with variables containing variables. %PATH% already contains variables so while I'm in my for loop %%A is a variable holding a string like so:%JAVA_HOME%/bin; The problem is when I try to save this string or echo it it evaluates to the value of the variable. Which is C:\PROGRA~1\Java\jdk1.8.0_25\bin; I want to keep it in its original form – user1543871 Feb 01 '15 at 19:49
  • Ah, I see the difference now, thanks for clarifying. – famousgarkin Feb 01 '15 at 20:19
  • If possible, use `pathman.exe` instead of `setx.exe`. It is designed to solve exactly this problem. – Harry Johnston Feb 01 '15 at 21:00
  • possible duplicate of [Why are other folder paths also added to system PATH with SetX and not only the specified folder path?](http://stackoverflow.com/questions/25915767/why-are-other-folder-paths-also-added-to-system-path-with-setx-and-not-only-the) – Mofi Feb 03 '15 at 07:07

2 Answers2

2

I could be mistaken about this, but I suspect that part of your issue is the way %PATH% is stored in the registry. The type of value is REG_EXPAND_SZ, which I'm guessing expands all the embedded variables at the time %PATH% is defined. The reason I suspect this is that no matter whether which retrieval method you use:

echo %PATH%

setlocal enabledelayedexpansion
echo !PATH!

set PATH

They all display each variable within PATH already expanded.

So, in order to work around this, I think you need to retrieve PATH directly from the registry.

@echo off
setlocal

for /f "tokens=2*" %%I in (
    'reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v path'
) do set "HKLMpath=%%J"

for /f "tokens=2*" %%I in (
    'reg query "HKCU\Environment" /v path 2^>NUL'
) do set "HKCUpath=%%J"

setlocal enabledelayedexpansion
echo(!HKLMpath!
if defined HKCUpath echo(!HKCUpath!

And then, as long as you keep the delayedexpansion style, you can leave the component variables unexpanded.

That's half the answer, anyway. I don't feel like messing with my %PATH% for further testing, but you might find this question useful if you have problems with setx and keeping your variables collapsed.

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
1

I did experiment with the %PATH% and @rojo is correct - You cannot have variables in the %PATH%

There were quite a few bugs in the command excerpt you posted, which I fixed. I'm posting below so you can see them.

I truly dislike the single command line FOR loop, but I left it that way, as you started with that!

: Script to remove certain directories from the search path
::
:: We need to use!! variable expansion
setlocal enabledelayedexpansion
:: Preset some variables for testing
set stringToFind=D:
:: newPath must be initialised to nothing before we start
set newPath=
:: Just for testing we could put a variable name in the path
SET PATH=%%JAVA_THING%%;%PATH%
:: The following loop fixes bugs with embedded quotes and spaces and too many ;
FOR %%A IN ("%PATH:;=";"%") DO ECHO;%%A | FINDSTR /I /C:%stringToFind% >NUL && SET found=true || IF !newPath!. == . ( SET newPath=%%~A) ELSE ( SET newPath=!newPath!;%%~A)
echo;!newPath!
:: The echo will confirm the %variables% are in the path
:: setx MYPATH "!newPath!"
::  The above setx removes the %variables% from the PATH
set path2=!newPath:%%=%%%%!
echo;%path2%
:: Now We can see the %'s are protected
setx MYPATH "!path2!"
:: But when we check the PATH in a new environment we cannot put invalid paths in place
exit /b
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129