2017-02-09 132 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