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.

5
  • possible duplicate of how to escape % at cmd setx? Commented Feb 1, 2015 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 Commented Feb 1, 2015 at 19:49
  • Ah, I see the difference now, thanks for clarifying. Commented Feb 1, 2015 at 20:19
  • If possible, use pathman.exe instead of setx.exe. It is designed to solve exactly this problem. Commented Feb 1, 2015 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? Commented Feb 3, 2015 at 7:07

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.