1

I have this batch file to append a environment variable if not exists

setLocal EnableDelayedExpansion
set echo off                        

set envPath=%PATH%
set comPath=";D:\Package\Libraries\Lib"

if x%envPath:comPath=%==x%envPath% (
    setx PATH "%PATH%;D:\Package\Libraries\Lib" /M
)
pause

But its not working and says file was unexpected this time

I wrote based on Batch file: Find if substring is in string (not in a file)

Community
  • 1
  • 1
Billa
  • 5,226
  • 23
  • 61
  • 105
  • You need `if "!envPath:%comPath%=!"=="!envPath!"` ... your form tests if the literal string `comPath` is present; you want to see if the _contents_ of `comPath` is present. For this you need to use both `%` and `!` references. – TripeHound Aug 01 '16 at 10:32
  • @Billa, you took an example code which should not be used. See anwers on [Why are other folder paths also added to system PATH with SetX and not only the specified folder path?](http://stackoverflow.com/questions/25915767) and [Setting path environment variable in batch file only once on Win7](http://stackoverflow.com/questions/31885906) and [How can I use a .bat file to remove specific tokens from the PATH environment variable?](http://stackoverflow.com/a/38664286/3074564) for better solutions and an explanation why not using local __PATH__ on updating system __PATH__. – Mofi Aug 01 '16 at 16:36
  • 1
    Detecting whether a value exists within PATH is much more complicated than you realize. Have a look at [How to check if directory exists in %PATH%?](http://stackoverflow.com/a/8046515/1012053) – dbenham Aug 01 '16 at 18:33
  • Thanks for the links. Very useful for every reader of this thread to outline details of the complex and far not obvious issue of updating global PATH var. – sambul35 Aug 02 '16 at 10:53

1 Answers1

2

As mentioned in the above comment, use delayed expansion in the main string, and regular expansion in the replace string. Run this batch as Admin from shortcut or from Admin Cmd Prompt:

@echo off
setLocal EnableDelayedExpansion
set "comPath=D:\Package\Libraries\Lib"                     
set "envPath=%PATH%" & set "Separator="
if not "%envPath:~-1%" == ";" set "Separator=;"

if "!envPath:%comPath%=!"=="%envPath%" (
    setx PATH "%PATH%%Separator%%comPath%" /M )
timeout 5
exit /b

Note that updated PATH will be re-read from Registry only upon Cmd restart. If you need to use the amended PATH in the same batch, use SET instead of SETX to set the PATH temporarily for that Cmd session.

In a similar construct, if your extra path comPath is set inside IF or FOR loop, use call set "PATH=%%envPath:!comPath!=%%" instead.

sambul35
  • 1,058
  • 14
  • 22
  • why `timeout 5` and `exit` needed? – Billa Aug 01 '16 at 14:24
  • If this is your entire script, _exit /b_ will cleanup Cmd memory, so you can start a new batch from the same open Cmd window. And _timeout_ is usually added for debugging, when you start a batch by doubleclick, and need some time to read its echo or error output before its window closes. It just gives you the construct to test code variations. :) – sambul35 Aug 01 '16 at 14:40
  • Tried this but got error again. Also I modified `set "comPath=;D:\Package\Libraries\Lib"` to `set comPath=";D:\Package\Libraries\Lib"` – Billa Aug 01 '16 at 14:43
  • Try this without modifying anything **at all**. If error, post the exact error printout. – sambul35 Aug 01 '16 at 14:47
  • I ran as it is. It didn't add the new value. It just ran the timer `Waiting for 5-0 seconds` and did nothing – Billa Aug 01 '16 at 15:40
  • @Billa You clearly missed the bit that said "Note that updated PATH will be re-read from Registry only upon Cmd restart." – DavidPostill Aug 01 '16 at 15:47
  • @Billa I tested it in Win10 64-bit, and it works _perfect_. To update the PATH, you must run the batch as Admin. What Windows version do you use? Also, after you run the script, close Cmd window, start Cmd again, and type echo %PATH%. It should list your path among others, but they are sorted in alphabet order, not necessarily at the end. – sambul35 Aug 01 '16 at 15:48
  • Is there any reason why variable declaration used like `set "comPath=;D:\Package\Libraries\Lib"`? instead of `set comPath=";D:\Package\Libraries\Lib"` – Billa Aug 01 '16 at 16:08
  • Print your PATH var. Do you see any path shown with parentheses? Replace function wouldn't work, as it can't find such. :) – sambul35 Aug 01 '16 at 16:41
  • If I restart the machine and run the script, its adding again.. so getting duplicate entries... :( – Billa Aug 02 '16 at 09:33
  • @Billa I updated the answer, after reading the newly added comments links to your question by _Mofi_ and _dbenham_. Tested again, and works pretty well. – sambul35 Aug 02 '16 at 11:26
  • Got it. But when I ran the previous version with same SETX /M it appending every time when i restart and run – Billa Aug 02 '16 at 15:59
  • It was due to extra `;` – sambul35 Aug 02 '16 at 16:03