As described in detail in answer on Why are other folder paths also added to system PATH with SetX and not only the specified folder path? it is not good to modify system or user PATH
from within a batch file by simply overwriting or appending a folder path to PATH
stored in registry using the local PATH
.
One solution for this task to add current directory path to user PATH
is using this code on Windows Vista or later released versions of Windows:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%System32
eg.exe query "HKEY_CURRENT_USEREnvironment" /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%System32setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%System32setx.exe Path "%CD%" >nul
) else (
%SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /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%System32setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%System32setx.exe Path "!PathToSet!" >nul
) else (
set "ValueType=REG_EXPAND_SZ"
if "!PathToSet:%%=!" == "!PathToSet!" set "ValueType=REG_SZ"
%SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /f /v Path /t !ValueType! /d "!PathToSet!" >nul
)
)
endlocal
endlocal
The disadvantage of this solution is a user PATH
being finally for example C:Temp;C:TempOther Folder;C:TempOne More Folder
when current directory is first C:Temp
, on next run of the batch file?C:TempOther Folder
and C:TempOne More Folder
on third execution of the batch file.
The solution to avoid this is a definition of an application specific environment variable called in next batch file MyAppPath
which is always overwritten on execution of the batch file. To the user PATH
is added only the reference to the environment variable MyAppPath
if not already existing in user PATH
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "UseSetx=1"
if not "%CD:~1024,1%" == "" set "UseSetx="
if not exist %SystemRoot%System32setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%System32setx.exe MyAppPath "%CD%" >nul
) else (
%SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /f /v MyAppPath /t REG_SZ /d "%CD%" >nul
)
set "UserPath="
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%System32
eg.exe query "HKEY_CURRENT_USEREnvironment" /v "Path" 2^>nul') do (
if /I "%%N" == "Path" (
set "UserPath=%%P"
if defined UserPath goto CheckPath
)
)
if exist %SystemRoot%System32setx.exe (
%SystemRoot%System32setx.exe Path "%%MyAppPath%%" >nul
) else (
%SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /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%System32setx.exe set "UseSetx="
if defined UseSetx (
%SystemRoot%System32setx.exe Path "!PathToSet!" >nul
) else (
%SystemRoot%System32
eg.exe ADD "HKCUEnvironment" /f /v Path /t REG_EXPAND_SZ /d "!PathToSet!" >nul
)
)
endlocal
endlocal
In this case user PATH
as stored in registry contains always just %MyAppPath%
and registry value is of type REG_EXPAND_SZ. The value of environment variable MyAppPath
is also stored in registry, but is of type REG_SZ. The value of MyAppPath
is updated to current directory path on each execution of the batch file. So the user PATH
in registry does not get longer and longer on each execution of a batch file from a different folder than before.
In general an application or application suite is not good coded if its application folder or one of its subfolders must be in local PATH
on execution of the application or any application from the suite to work properly at all. The application or application suite can store its installation path also somewhere else in registry like App Paths
or in a file in a subfolder of %APPDATA%
(user account related standard application data path) from which it can be read on next run. An installer package should modify user or system PATH
only if this application is most likely executed mainly from within a command prompt window by a user.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
reg /?
reg add /?
reg query /?
set /?
setlocal /?
setx /?
Following should be also read:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…