2

I am writing a script for windows to install a selenium service that also sets the PATH for the chrome and ie drivers, but just setting them every time the script runs (if anything is updated) will eventually run into appending the same variables to the end over and over. I tried this:

setx IEDRIVER "%~dp0..\ie" /m
setx CHROMEDRIVER "%~dp0..\chrome" /m
if not x%PATH:IEDRIVER=%==x%PATH% setx path "%PATH%IEDRIVER;" /m
if not x%PATH:CHROMEDRIVER=%==x%PATH% setx path "%PATH%CHROMEDRIVER;" /m

but I get the error:

C:\Windows was unexpected at this time.

The end goal is to check to see if a variable is in the path, if it isn't set that variable.

Allen
  • 127
  • 1
  • 1
  • 9

2 Answers2

4

Part of the problem is that %PATH% contains spaces. When it's likely either side of the comparison operator in an if statement contains spaces, you should quote both arguments.

if not "%PATH:substr=repl%"=="%PATH%" do stuff....

Next, you're trying to supply a variable as a substring to another variable. When you do this, you need delayed expansion on the outer variable.

setlocal enabledelayedexpansion
if not "!PATH:%IEDRIVER%=!"=="!PATH!" do stuff....
endlocal

Now. Rather than checking to see whether the absolute paths exist within PATH, it'd be better to check whether some file within your ie and chrome directories are accessible to PATH. You can do this with for variable expansion syntax.

for %%I in (ie chrome) do set %%I=
for %%I in (fileInIE.ext) do set "ie=%%~$PATH:I"
for %%I in (fileInChrome.ext) do set "chrome=%%~$PATH:I"
if defined ie....
if defined chrome...

But the biggest issue is that using setx to modify your %PATH% is destructive and ought to be avoided. The registry value containing PATH intentionally uses unexpanded variables, and is held in a data type that expands them at runtime. Using setx expands them all too early. It's better to modify the registry directly if you want to modify your path programmatically. It's not as easy, but it's less destructive.

@echo off
setlocal

for %%I in ("%~dp0..\ie") do set "IEDRIVER=%%~fI"
for %%I in ("%~dp0..\chrome") do set "CHROMEDRIVER=%%~fI"
for %%I in (ie chrome) do set %%I=
for %%I in (fileInIE.ext) do set "ie=%%~$PATH:I"
for %%I in (fileInChrome.ext) do set "chrome=%%~$PATH:I"

if not defined ie call :append_path "%IEDRIVER%"
if not defined chrome call :append_path "%CHROMEDRIVER%"

goto :EOF

:append_path <val>
set "env=HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
for /f "tokens=2*" %%I in ('reg query "%env%" /v Path ^| find /i "REG_EXPAND_SZ"') do (

    rem // make addition persistent through reboots
    reg add "%env%" /f /v Path /t REG_EXPAND_SZ /d "%%J;%~1"

    rem // apply change to the current process
    for %%a in ("%%J;%~1") do (path %%~a)
)

rem // use setx to set a temporary throwaway value to trigger a WM_SETTINGCHANGE
rem // applies change to new console windows without requiring a reboot
(setx /m foo bar & reg delete "%env%" /f /v foo) >NUL 2>NUL

color 4E
echo Warning: %%PATH%% has changed.  Reopen the console to inherit the changes.

goto :EOF
rojo
  • 24,000
  • 5
  • 55
  • 101
  • Excellent answer! But `set "IEDRIVER=%~dp0..\ie"` results to `fullScriptPath\..\ie` literally. How that `\..\ ` (i.e. obvious _parent folder_) will be resolved in `path` environment variable? In any case, it appears to be an ugly thing... I'd use something like `set "batDir=%~dp0"` & `set "batDir=%batDir:~0,-1%"` & `for %%G in ("%batDir%") do set "Parent=%%~dpG"` & `set "IEDRIVER=%Parent%ie"` – JosefZ Apr 03 '15 at 21:43
  • 1
    Or `for %%I in ("%~dp0..\ie") do set "IEDRIVER=%%~fI"` would also work. My purpose was more to teach than to fix, and I didn't want to make the script completely unrecognizable to the OP. I guess my answer ended up way beyond that anyway. I'll fix the `..` parts as you suggest. – rojo Apr 04 '15 at 01:21
  • Perfect hit with `%%~fI` as you do not need _parent folder_ actually. However, I've tested that nasty `\..\ ` in `path` and it works well... – JosefZ Apr 04 '15 at 12:11
0

Setx refuses to add an existing path to the path.

Serenity
  • 9
  • 3