将目录添加到路径环境变量 [英] adding directory to path environment variable
问题描述
我的要求是在安装我的应用程序时,将目录之一添加到Windows中的 path 环境变量中,并将其从 中删除使用批处理文件进行卸载时的路径 环境变量.
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.
在与此相关的stackoverflow答案之一中,建议以下将目录添加到路径环境变量.
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?
推荐答案
您需要检查path
变量的用户部分是否为空,例如用于添加目录,如下所示:
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
请注意,我使用reg add
而不是 setx
命令.另请参见此Rojo的答案以获取详尽的解释.
Note that I use reg add
instead of setx
command. See also this Rojo's answer for exhaustive explanation.
输出.
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.
但是,检查path
密钥(用户或计算机范围的密钥)是否包含特定目录并不是一件容易的事.例如,path
中的某些条目包含尾随的\
反斜杠,而其他条目则不包含.此外,在path
注册表值REG_EXPAND_SZ
中的某些条目可能在其他环境变量(例如, %ProgramFiles%\SomeApp
代替C:\Program Files\SomeApp
等.
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.
以下复杂脚本可能有助于分析Windows path
环境变量(请注意,如果由于
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
这篇关于将目录添加到路径环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!