Lilo
Lilo

Reputation: 341

Remove unwanted directory from PATH using cmd file

I found a solution to remove a certain directory from the environment variable PATH directly via Windows commandline. But I would like to achieve the same result by issuing the command from within a cmd file.

What I can do is echoing the result I want to set PATH to if I put

echo %PATH:D:\dir-path;=%

into my cmd file. But if I write

set PATH=%PATH:D:\dir-path;=%

PATH contains only the directory I wanted to remove.

Furthermore I want to use a variable for the director path but if I try that the result is even worse. I put

set dirPath=D:\dir-path
echo %PATH:%dirPath%;=%

and all I get is dirPath;=.

I don't know how to fix this so I would be really grateful if someone could assist.

EDIT 1

As suggested by @Anders I now have:

@echo off

set exampleRemoveDir=d:\bar

REM If I use %exampleRemoveDir% it does not work at all.
call :removeFromPath exampleRemoveDir & set result=%ERRORLEVEL%

:removeFromPath
set removeDir=%~1

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removeDir%;=!
if "%_%" == "%PATH%" set _=!PATH:%removeDir%=!
endlocal & set PATH=%_%
echo %PATH%
exit /b 0

But with that solution PATH still remains unchanged. The code works flawlessly if I don't scope the removing step bit since I want to do that for multiple directories it would be a real pain to not have such a nice helper doing the work for me.

EDIT 2

Since this seems to be more complex than I thought here is my complete unchanged script so far.

@echo off
::  Switching Perl version from ActivePerl to StrawberryPerl or the other way round depending on which paths are set in
::  PATH.

::  Directories for ActivePerl
set activePerl_SiteBinPath=D:\ProgramFiles\ActivePerl\site\bin
set activePerl_BinPath=D:\ProgramFiles\ActivePerl\bin

::  Directories for StrawberryPerl
set strawberryPerl_SiteBinPath=D:\ProgramFiles\StrawberryPerl\perl\site\bin
set strawberryPerl_BinCPath=D:\ProgramFiles\StrawberryPerl\c\bin
set strawberryPerl_BinPath=D:\ProgramFiles\StrawberryPerl\perl\bin

:: Determine which of the directories are present in PATH and which are not.
call :isInPath %activePerl_SiteBinPath% & set foundActivePerl_SiteBinPath=%ERRORLEVEL%
call :isInPath %activePerl_BinPath% & set foundActivePerl_BinPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_SiteBinPath% & set foundStrawberryPerl_SiteBinPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_BinCPath% & set foundStrawberryPerl_BinCPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_BinPath% & set foundStrawberryPerl_BinPath=%ERRORLEVEL%

:: Test
call :removeFromPath %strawberryPerl_SiteBinPath% & set removedStrawberryPerl_SiteBinPath=%ERRORLEVEL%

rem if /i %foundActivePerl_SiteBinPath% equ 0 if /i %foundActivePerl_BinPath% equ 0 (
rem     if /i %foundStrawberryPerl_SiteBinPath% neq 0 if /i %foundStrawberryPerl_BinPath% neq 0 if  /i %foundStrawberryPerl_BinCPath% neq 0 (
rem         echo Switching from ActivePerl to StrawberryPerl.
rem         TODO
rem         exit /b 0
rem     )
rem )
rem 
rem if /i %foundStrawberryPerl_SiteBinPath% equ 0 if /i %foundStrawberryPerl_BinPath% equ 0 if /i %foundStrawberryPerl_BinCPath% equ 0 (
rem     if /i %foundActivePerl_SiteBinPath% neq 0 if /i %foundActivePerl_BinPath% neq 0 (
rem         echo Switching from StrawberryPerl to ActivePerl.
rem         TODO
rem         exit /b 0
rem     )
rem )

:: Error
:: TODO
exit /b

:isInPath
::  Tests if the path stored within variable pathVar exists within %PATH%.
::
::  The result is returned as the ERRORLEVEL:
::      0 if the pathVar path is found in %PATH%.
::      1 if pathVar path is not found in %PATH%.
::      2 if parhVar path is missing or undefined.

:: Error checking
if "%~1"=="" exit /b 2

set pathVar=%~1

for /f %%i in ('echo ";%%PATH%%;" ^| find /c /i ";%pathVar%;"') do set /a foundPathVar=%%i

if /i %foundPathVar% equ 0 (
    exit /b 1
)
exit b/ 0

:removeFromPath
::  Removes a given directory from environment variable PATH if the directory exists within PATH.
::
::  The result is returned as the ERRORLEVEL:
::      0 if the given directory was removed from PATH or if it didn't exist in PATH.
::      1 if no directory was given or the directory is undefined.

:: Error checking
if "%~1"=="" exit /b 2

set removeDir=%~1

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removeDir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removeDir%=!
endlocal & set PATH=%_%
echo %PATH%

exit /b 0

EDIT 3

Thanks to @Anders removing the directory from path now works fine. I removed the wrong check for undefined parameter above and add % around the parameter of function calls. But somehow :isInPath now always returns zero. As far as I am concerned this already worked... :/ Furthermore, with the current code (added % to all function parameters) the cmd always directly closes irrespective of a pause after the call of :removeFromPath. It's infuriatingly!

Upvotes: 1

Views: 6390

Answers (1)

Anders
Anders

Reputation: 101756

You need to use delayed expansion if you want to use another variable as part of the variable substitution. You also need to deal with the possibility that the path you want to remove is at the end of %path% and therefore not terminated by a ;.

@echo off

set removedir=d:\bar
set PATH=c:\foo;%removedir%;y:\baz&REM Set example %path%

echo Starting with %%PATH%% set to %PATH%

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removedir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removedir%=!
endlocal & set PATH=%_%

echo %%PATH%% is now %PATH%

and here as a helper function:

@echo off
goto start

:removeFromPath 
echo.Debug: Starting function with remove=%~1 and %%PATH%%=%PATH%
setlocal enableextensions enabledelayedexpansion
set removedir=%~1
set _=!PATH:%removedir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removedir%=!
endlocal & set PATH=%_%
echo.Debug: Ending function with %%PATH%%=%PATH%
goto :EOF


:start
set exampleremovedir=d:\bar
set PATH=c:\foo;%exampleremovedir%;y:\baz&REM Set example %path%

echo Starting with %%PATH%% set to %PATH%

call :removeFromPath %exampleremovedir%

echo %%PATH%% is now %PATH%

Upvotes: 2

Related Questions