【问题标题】:Adding the current directory to Windows path permanently将当前目录永久添加到 Windows 路径
【发布时间】:2018-04-14 16:10:03
【问题描述】:

我正在尝试将当前目录(从命令行)永久添加到 Windows 路径,但我在实现这一点时遇到了严重问题。

我最初的尝试是:

set PATH=%PATH%;%cd%

但是,这只适用于当前会话;只要我关闭命令行窗口,PATH 环境变量就会保留它之前的值。

接下来,我尝试了:

setx PATH=%PATH%;%cd%

根据我在此处找到的一些答案,这可能适用于 Windows 7 和 8,但在 Windows 10 中,setx 命令具有三种工作方式:

Syntax 1:
    SETX [/S system [/U [domain\]user [/P [password]]]] var value [/M]

Syntax 2:
    SETX [/S system [/U [domain\]user [/P [password]]]] var /K regpath [/M]

Syntax 3:
    SETX [/S system [/U [domain\]user [/P [password]]]]
         /F file {var {/A x,y | /R x,y string}[/M] | /X} [/D delimiters]

长话短说,我无法让它工作:

ERROR: Invalid syntax. Default option is not allowed more than '2' time(s).

我怎样才能以最简单的方式完成我的目标?

如果每个 Windows 版本有不同的语法,那么我也很乐意获得此信息。

【问题讨论】:

  • 我会尝试省略=
  • @Magoo:有趣,我就是这么做的;不过运气不好……
  • @Magoo:我得到ERROR: Invalid syntax. Default option is not allowed more than '2' time(s).
  • @Magoo:好的,第二个参数周围的双引号解决了这个问题:setx PATH "%PATH%;%cd%"。谢谢!!!!!!
  • @Magoo:更准确地说:setx PATH "%cd%"。我上面提到的语法“复制”了整个 PATH(并且大部分将结果截断为 1024 个字符),这使它成为一个非常糟糕的主意。

标签: batch-file command-line path environment-variables


【解决方案1】:

正如Why are other folder paths also added to system PATH with SetX and not only the specified folder path? 的回答中详细描述的那样,通过简单地覆盖或附加一个批处理文件来修改 systemuser 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%(用户帐户相关标准应用程序数据路径)的子文件夹中的文件,下次运行时可以从中读取。安装程序包应该修改 usersystem PATH,前提是此应用程序很可能主要由用户在命令提示符窗口中执行。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • reg /?
  • reg add /?
  • reg query /?
  • set /?
  • setlocal /?
  • setx /?

还应阅读以下内容:

【讨论】:

    【解决方案2】:

    简单的解决方案:

    setx 的语法与set 的语法略有不同。

    有了set,我会这样做:

    set PATH=%PATH%;%cd%
    

    对于setx,我需要这样做:

    setx PATH "%cd"
    

    第一个参数指定环境变量的名称。

    第二个参数指定要添加到此变量的值。

    当第二个参数包含空格时,需要双引号。

    顺便说一句,set 也可能是这种情况。

    【讨论】:

    • @goodvibration,这将覆盖用户的当前值PATH。如果您想为每个用户 PATH 轻松访问它,那么添加一个扩展的 MYPATH 变量(即没有百分比变量)。然后在用户PATH 中可以包含%MYPATH%。这个MYPATH 值将存储为REG_SZ 值,因为它没有变量。这很重要,因为这意味着它在加载REG_EXPAND_SZ 值(例如PATH)之前在第一遍中加载。两次加载允许REG_EXPAND_SZ 值可靠地依赖于REG_SZ 值。
    • @eryksun:您能逐步提供书面答案吗?我很难得出结论我到底应该做什么?理想情况下,我想执行一个或多个命令行。谢谢!
    • 我的建议只是为了让将来扩展用户PATH 变得更简单。例如,假设存在MYPATH,您可以运行setx MYPATH "%MYPATH%;%CD%"。您仍然需要修改HKCU\Environment 中用户的PATH 值以包含未扩展的%MYPATH% 变量。为此,您可以使用 GUI 环境变量编辑器,或改编 Mofi 的结合 reg.exe 和 setx.exe 的代码。
    • @eryksun :所以没有办法完全自动将当前工作目录添加到 PATH 以使系统的所有部分保持最新(注册表等)?
    • @shellter,正如 Mofi 的代码所示,在脚本中为当前用户执行此操作的方法是使用 reg.exe 从“HKCU\Environment”读取“PATH”,附加到它,并用 setx.exe 将其写回。使用 setx.exe 写入值会广播 WM_SETTINGCHANGE 消息,以使 Explorer 从注册表中重新加载其环境,因此随后从 Explorer 运行的进程将拥有更新的环境。
    猜你喜欢
    • 2015-07-28
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    相关资源
    最近更新 更多