2017-02-09 130 views
0

我的要求是,在安装我的应用程序一次添加一个目录来路径环境变量在Windows和当时从路径中删除同一环境变量使用批处理文件卸载。添加目录到PATH环境变量

在与此相关的一个stackoverflow答案中建议将以下路径添加到路径环境变量中。

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

它添加到路径变量,但是当我尝试再添加一个时,它会覆盖已添加的现有值。如何避免这种情况?

如何从路径环境变量中删除我添加的目录路径?

回答

0

你应该能够使用它的现有价值是这样的:

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

要删除它,你大概可以做这样的事情:

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

这将取代它的路径没有任何东西可以删除它。

0

您需要检查path变量的用户部分是否为空,例如,添加目录如下:

@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 

请注意,我用reg add代替setx command。有关详尽的解释,另请参阅this Rojo's answer

输出

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> 

上面结果可以看出,如果key为空只检查不足以作为运行两次将增加相同的目录两次为好。

但是,检查path键(用户或机器范围)是否包含特定目录不是这样简单的任务。例如,path中的一些条目包含尾随的\反斜杠,而其他条目则不包含。此外,REG_EXPAND_SZ的登记值中的一些条目可能是在其他环境变量中纠结的。的%ProgramFiles%\SomeApp代替C:\Program Files\SomeApp

下复杂的脚本可以帮助分析的Windows path环境变量(请注意,它可能显示不正确的值,如果路径中包含因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