adding directory to path environment variable

2019-09-19 06:31发布

My requirement is to add one of the directory to path environment variable in windows at the time of installing my application and remove the same from path environment variable at the time of uninstallation using batch file.

In one of the stackoverflow answer related to this suggested the following to add a directory to path environment variable.

setx path C:\Program Files (x86)\MyApp\

It is adding to path variable but when I try to add one more, it overwrites the existing value which I have added. How to avoid this?

How to remove the directory path which I have added from path environment variable?

2条回答
欢心
2楼-- · 2019-09-19 06:56

You should be able to use the existing value of it like this:

setx PATH %PATH%;C:\Program Files (x86)\MyApp\

To remove it you could probably do something like this:

setx PATH=%PATH:;C:\Program Files (x86)\MyApp\=%

Which would substitute the path it was given with nothing to delete it.

查看更多
相关推荐>>
3楼-- · 2019-09-19 07:08

You need to check if user's part of path variable is empty, e.g. for adding a directory as follows:

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_apppath=C:\Program Files (x86)\MyApp\"

set "_keyBase=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager"   machine
set "_keyBase=HKCU"                                                    user

set "_dataTyp="
set "_dataOld="
for /F "tokens=2,*" %%G in (' 
  reg query "%_keyBase%\Environment" -V path ^| findstr /I "\<path\>"
  ') do (
      set "_dataTyp=%%G"
      set "_dataOld=%%H"
)
if defined _dataOld (
    set "_dataNew=%_apppath%;%_dataOld%"
) else (
    set "_dataNew=%_dataOld%"
    set "_dataTyp=REG_SZ"
)
rem debugging output: show script variables
set _

if /I "%~1" EQU "write" (
    reg add "%_keyBase%\Environment" -V path -T %_dataTyp% -d "%_dataNew%" -F
) else (
    rem debugging output
    ECHO reg add "%_keyBase%\Environment" -V path -T %_dataTyp% -d "%_dataNew%" -F
) 
ENDLOCAL
goto :eof

Note that I use reg add instead of setx command. See also this Rojo's answer for exhaustive explanation.

Output.

d:\bat> D:\bat\SO\42140086.bat
_apppath=C:\Program Files (x86)\MyApp\
_dataNew=C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote
_dataOld=D:\bare!;D:\Remote
_dataTyp=REG_EXPAND_SZ
_keyBase=HKCU
reg add "HKCU\Environment" -V path -T REG_EXPAND_SZ -d "C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote" -F

d:\bat> D:\bat\SO\42140086.bat write
_apppath=C:\Program Files (x86)\MyApp\
_dataNew=C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote
_dataOld=D:\bare!;D:\Remote
_dataTyp=REG_EXPAND_SZ
_keyBase=HKCU
The operation completed successfully.

d:\bat> D:\bat\SO\42140086.bat
_apppath=C:\Program Files (x86)\MyApp\
_dataNew=C:\Program Files (x86)\MyApp\;C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote
_dataOld=C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote
_dataTyp=REG_EXPAND_SZ
_keyBase=HKCU
reg add "HKCU\Environment" -V path -T REG_EXPAND_SZ -d "C:\Program Files (x86)\MyApp\;C:\Program Files (x86)\MyApp\;D:\bare!;D:\Remote" -F

d:\bat>

Above output shows that the only check if a key is empty does not suffice as running it twice would add the same directory twice as well.

However, checking if a path key (user or machine-wide) contains a particular directory is not such simple task. For instance, some entries in path contain a trailing \ backslash while others don't. Moreover, some entries in a path registry value of REG_EXPAND_SZ could be tangled in other environment variables e.g. %ProgramFiles%\SomeApp instead of C:\Program Files\SomeApp etc.

The following complex script could help to analyse Windows path environment variables (note that it could show incorrect values if a path contains an exclamation mark ! due to enabled delayed expansion):

@ECHO OFF
SETLOCAL enableextensions enabledelayedexpansion
echo --- %date% %time% %~nx0 %*  
if /I "%~1" EQU "dir" (
    set path
    Call :printPath path "" dir
    ENDLOCAL
    goto :eof
)

set pathext

Call :duplicity pathext

Call :printPath path ""

rem debugging set "wrongpath=%path%;%SystemRoot%\\"
rem debugging Call :duplicity wrongpath

Call :duplicity path

set "HKCU_type="
set "HKCU_path="
for /F "tokens=2*" %%G in (
  'reg query HKCU\Environment /v Path 2^>NUL ^|findstr /I "path"'
  ) do (
    set "HKCU_type=%%G"
    set "HKCU_path=%%H"
  ) 
Call :printPath HKCU_path %HKCU_type%
if /I "%HKCU_type%"=="REG_EXPAND_SZ" Call :printPath HKCU_path %HKCU_type% Expanded

set "HKLM_type="
set "HKLM_path="
set "qqqq=HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
for /F "tokens=2*" %%G in ('reg query "%qqqq%" /v Path^|findstr /I "path"'
  ) do (
    set "HKLM_type=%%G" 
    set "HKLM_path=%%H" 
  ) 
Call :printPath HKLM_path %HKLM_type%
if /I "%HKLM_type%"=="REG_EXPAND_SZ" Call :printPath HKLM_path %HKLM_type% Expanded

:dirOnly
Call :deflatePath HKLM_path %HKLM_type%
    rem echo "!NewPath:%%=%%%%!"

pause
set HK
ENDLOCAL&call set "NewPath=%NewPath%"
goto :eof

:printPath
echo(
echo %~0 %~1 %~2 %~3
if "!%~1!" NEQ "" (
  set "ggg="!%~1:;=" "!""
  rem set "ggg=!ggg:\"="!"
  for %%G in (!ggg!) do (
    if /I "%~3" NEQ "expanded" (
        if /I "%~3" EQU "dir" (
            echo(
            echo %~0 %~1 %~2 %%~G
            set "_partpath=%%~G"
            if /I "!_partpath:%SystemRoot%=!" EQU "%%~G" (
                dir /B /A:-D "%%~G" | findstr /I "%pathext:;=$ %$"
                rem timeout /T 3 /NOBREAK >NUL
            ) else (
                echo %~0 %~1 %~2 System default 
            )
        ) else (
            echo %%~G
        ) 
    ) else (
        call echo %%~G
    )
  )
  echo(
  echo tested using next findstr regex: 
  echo "%pathext:;=$ %$"
)
goto :eof

:duplicity
echo(
echo %~0 %~1 %~2
set /A "ii=0"
set "ggg="!%~1:;=" "!""
set "ggg=!ggg:\"="!"
for %%G in (!ggg!) do (
  set /A "ii+=1"
  set /A "jj=0"
  for %%g in (!ggg!) do (
    set /A "jj+=1"
    if /I "%%~G"=="%%~g" if !ii! LSS !jj! echo !ii!, !jj!: %%~g 
  )
)
goto :eof

:deflatePath
echo(
echo %~0 %~1 %~2
set "ggg="!%~1:;=" "!""
rem set "ggg=!ggg:\"="!"
set "NewPath="
for %%G in (!ggg!) do (
  set "item=%%~G"
  set "meti="
  call :deflateItem "ProgramFiles(x86)"
  if defined meti (
    rem echo # !item!
  ) else (
    call :deflateItem "ProgramFiles"
    if defined meti (
      rem echo # !item!
    ) else (
      call :deflateItem "SystemRoot"
      if defined meti (
        rem echo # !item!
      ) else (
        rem echo = !item:%%=%%%%!
      )
    )
  )
  if defined NewPath (
    set "NewPath=!NewPath!;!item!"
  ) else (
    set "NewPath=!item!"
  )
)
echo !NewPath!
rem reg delete HKCU\Environment /v NewPath /f
rem setx NewPath "!NewPath!"
rem WARNING: The data being saved is truncated to 1024 characters.
rem reg query HKCU\Environment /v NewPath|findstr /I "NewPath"
goto :eof

:deflateItem
  set "meti=!%~1!"
  if "!meti!"=="!item!" (
    set "item=%%%~1%%"
  ) else (
    set "meti=!item:%meti%\=!"
    if "!meti!" == "!item!" (
      set "meti="
    ) else (
      set "item=%%%~1%%\!meti!"
    )
  )
goto :eof
查看更多
登录 后发表回答