正如Why are other folder paths also added to system PATH with SetX and not only the specified folder path? 的回答中详细描述的那样,通过简单地覆盖或附加一个批处理文件来修改 system 或 user PATH 是不好的使用本地 PATH 存储在注册表中的PATH 的文件夹路径。
将此任务添加到用户 PATH 的当前目录路径的一种解决方案是在 Windows Vista 或更高版本的 Windows 上使用此代码:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKEY_CURRENT_USER\Environment" /v "Path" 2^>nul') do (
if /I "%%N" == "Path" (
set "UserPath=%%P"
if defined UserPath goto CheckPath
)
)
set "UseSetx=1"
if not "%CD:~1024,1%" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%\System32\setx.exe Path "%CD%" >nul
) else (
%SystemRoot%\System32\reg.exe ADD "HKCU\Environment" /f /v Path /t REG_SZ /d "%CD%" >nul
)
endlocal
goto :EOF
:CheckPath
setlocal EnableDelayedExpansion
set "Separator="
if not "!UserPath:~-1!" == ";" set "Separator=;"
set "PathCheck=!UserPath!%Separator%"
if "!PathCheck:%CD%;=!" == "!PathCheck!" (
set "PathToSet=!UserPath!%Separator%%CD%"
set "UseSetx=1"
if not "!PathToSet:~1024,1!" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%\System32\setx.exe Path "!PathToSet!" >nul
) else (
set "ValueType=REG_EXPAND_SZ"
if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ"
%SystemRoot%\System32\reg.exe ADD "HKCU\Environment" /f /v Path /t !ValueType! /d "!PathToSet!" >nul
)
)
endlocal
endlocal
此解决方案的缺点是 用户 PATH 最终例如 C:\Temp;C:\Temp\Other Folder;C:\Temp\One More Folder 当当前目录是第一个 C:\Temp 时,下次运行批处理文件 C:\Temp\Other Folder 和 @987654337 @ 在第三次执行批处理文件时。
避免这种情况的解决方案是定义在下一个批处理文件MyAppPath 中调用的特定于应用程序的环境变量,该变量总是在执行批处理文件时被覆盖。 user PATH 仅添加对环境变量 MyAppPath 的引用(如果 user PATH 中尚不存在)。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "UseSetx=1"
if not "%CD:~1024,1%" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%\System32\setx.exe MyAppPath "%CD%" >nul
) else (
%SystemRoot%\System32\reg.exe ADD "HKCU\Environment" /f /v MyAppPath /t REG_SZ /d "%CD%" >nul
)
set "UserPath="
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKEY_CURRENT_USER\Environment" /v "Path" 2^>nul') do (
if /I "%%N" == "Path" (
set "UserPath=%%P"
if defined UserPath goto CheckPath
)
)
if exist %SystemRoot%\System32\setx.exe (
%SystemRoot%\System32\setx.exe Path "%%MyAppPath%%" >nul
) else (
%SystemRoot%\System32\reg.exe ADD "HKCU\Environment" /f /v Path /t REG_EXPAND_SZ /d "%%MyAppPath%%" >nul
)
endlocal
goto :EOF
:CheckPath
setlocal EnableDelayedExpansion
set "Separator="
if not "!UserPath:~-1!" == ";" set "Separator=;"
if "!UserPath:%%MyAppPath%%=!" == "!UserPath!" (
set "PathToSet=!UserPath!%Separator%%%MyAppPath%%"
set "UseSetx=1"
if not "!PathToSet:~1024,1!" == "" set "UseSetx="
if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%\System32\setx.exe Path "!PathToSet!" >nul
) else (
%SystemRoot%\System32\reg.exe ADD "HKCU\Environment" /f /v Path /t REG_EXPAND_SZ /d "!PathToSet!" >nul
)
)
endlocal
endlocal
在这种情况下 user PATH 存储在注册表中始终只包含 %MyAppPath% 并且注册表值的类型为 REG_EXPAND_SZ。环境变量MyAppPath 的值也存储在注册表中,但属于REG_SZ 类型。每次执行批处理文件时,MyAppPath 的值都会更新为当前目录路径。因此,注册表中的 用户 PATH 不会在每次从不同文件夹执行批处理文件时变得越来越长。
一般来说,如果应用程序或应用程序套件的应用程序文件夹或其子文件夹之一必须在 local PATH 中执行应用程序或套件中的任何应用程序才能正常工作,则应用程序或应用程序套件的编码不佳完全正确。应用程序或应用程序套件还可以将其安装路径存储在注册表中的其他位置,如App Paths 或%APPDATA%(用户帐户相关标准应用程序数据路径)的子文件夹中的文件,下次运行时可以从中读取。安装程序包应该修改 user 或 system PATH,前提是此应用程序很可能主要由用户在命令提示符窗口中执行。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
reg /?
reg add /?
reg query /?
set /?
setlocal /?
setx /?
还应阅读以下内容: