命令提示符中的系统变量路径不同

System Variable path is different in command prompt

我见过各种各样的问题,但我为此奋斗了一整天,所以请给我一些帮助:)

小故事:我在系统变量面板和 cmd 中有不同的 PATH 变量。不能 运行 exe 文件吗?

长话短说:我正在尝试安装 Ruby。尝试了不同的版本,但问题是一样的:我 更新了 我的 PATH 值, Ruby 在那里。 BUT 从 cmd 使用它时,无法识别 ruby。 echo %PATH% 给出的值与环境变量面板中的值不同!

第一个附件:环境变量面板:

用户变量的值: C:\Users\morifey\nvmw\nodejs\v0.10.36;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;"C:\Program Files\Intel\WiFi\bin\";"C:\Program Files\Common Files\Intel\WirelessCommon\";"C:\Program Files (x86)\Skype\Phone\";"C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x86";"C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x64";"C:\Program Files\nodejs\";C:\wamp\bin\php\php5.5.12;C:\ProgramData\ComposerSetup\bin;"C:\Program Files\TortoiseGit\bin";"C:\Program Files (x86)\Git\cmd";"C:\Program Files\Intel\WiFi\bin\";"C:\Program Files\Common Files\Intel\WirelessCommon\";C:\Users\morifey\AppData\Roaming\npm;C:\Ruby21\bin

系统变量的值: C:\Ruby21\bin;C:\Users\morifey\nvmw\nodejs\v0.10.36;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;"C:\Program Files\Intel\WiFi\bin\";"C:\Program Files\Common Files\Intel\WirelessCommon\";"C:\Program Files (x86)\Skype\Phone\";"C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x86";"C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x64";"C:\Program Files\nodejs\";C:\wamp\bin\php\php5.5.12;C:\ProgramData\ComposerSetup\bin;"C:\Program Files\TortoiseGit\bin";"C:\Program Files (x86)\Git\cmd";"C:\Program Files\Intel\WiFi\bin\";"C:\Program Files\Common Files\Intel\WirelessCommon\";"C:\Users\morifey\AppData\Roaming\npm";%SystemRoot%\system32;%SystemRoot%

我将它们与 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment - 它们 完全相同.

但是 我 运行 命令并使用 echo %PATH%。结果: C:\Users\morifey\nvmw\nodejs\v0.10.36;C:\ProgramData\Oracle\Java\javapath;C:\Win dows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPow erShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Int el\WirelessCommon\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\In tel\OpenCL SDK.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x64;C :\Program Files\nodejs\;C:\wamp\bin\php\php5.5.12;C:\ProgramData\ComposerSetup\b in;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\Git\cmd;C:\Program Fi les\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Users \morifey\AppData\Roaming\npm

Ruby 丢失了! 运行 作为管理员和非管理员都是一样的(实际上我只有一个管理员用户)。

我试过设置路径(通过 set 或 setx),更改注册表和环境变量 - 没有任何效果。我试过在有空格的路径中添加引号 (") - 没有区别。

Except 如果我 运行 cmd 作为管理员并使用 setx PATH "%PATH%;C:\Ruby21\bin"!然后,echo %PATH% returns 真实(更新)路径,我只能 运行 ruby 在此命令中。如果我关闭它,然后以管理员身份重新打开它 - 更改将丢失。

请告诉我如何处理这个问题?我只需要 运行 Ruby :)

Windows 7 旗舰版,Service Pack 1,64 位; 下载 Ruby(来自 http://rubyinstaller.org/downloads/)- Ruby 2.2.2(32 和 64 位),Ruby 2.1.6(32 和 64 位)- 结果都一样.


编辑:在几个人说我不需要引号之后,我删除了它们,并按照@eryksun 所说的放置。这是结果:

C:\Users\morifey>echo %PATH% C:\Users\morifey\nvmw\nodejs\v0.10.36;C:\ProgramData\Oracle\Java\javapath;C:\Win dows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPow erShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Int el\WirelessCommon\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\In tel\OpenCL SDK.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x64;C :\Program Files\nodejs\;C:\wamp\bin\php\php5.5.12;C:\ProgramData\ComposerSetup\b in;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\Git\cmd;C:\Program Fi les\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Users \morifey\AppData\Roaming\npm

有些输入重复了,这很奇怪: C:\Program Files\Intel\WiFi\bin\; C:\Program Files\Intel\WiFi\bin\; C:\Program Files\Common Files\Intel\WirelessCommon\; C:\Program Files\Common Files\Intel\WirelessCommon\; C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x86; C:\Program Files (x86)\Intel\OpenCL SDK.0\bin\x64; 尽管它们与我在系统变量路径中粘贴的行不同!


Update - 我使用 PowerShell 和 this 脚本来检查系统变量中是否存在重复。我正在上传带有结果的图片。 很奇怪路径正是应该的路径,但正如您所见,在 CMD 中我看到了不同的东西!


Update - 今天我尝试从 PowerShell 运行ning Ruby - 一切顺利。所以好像只有CMD不知道怎么回事!只是提醒你 - 重启没有帮助! :)

如果您的系统变量 PATH 长度超过某个值,它会在 cmd 提示符中被截断。根据这个 answer 这个值是 2047。删除重复项和 trim 你的路径,你会看到两个变量是相同的。

当您使用 SET 操作数时,它只会更改当前控制台的环境变量,这就是它的用途。要永久更改环境变量,您应该使用命令 SETX。并重启 windows。这 从技术上讲,您不能重启,只能重启所有服务,但很容易重启。

可能是命令提示符 auto运行 的问题(命令提示符在 运行 上设置 PATH): https://superuser.com/questions/727316/error-in-command-line-the-system-cannot-find-the-path-specified

原来是一个 bat 文件的问题,在我每次启动 cmd 时 运行,它修改了它的变量!感谢@eryksun 和@ılǝ - 似乎在注册表 (HKCU\Software\Microsoft\Command Processor\AutoRun) 中你可能有类似的东西。我的问题是 nvmw 包 (https://www.npmjs.com/package/nvmw) 安装时创建了这个 .bat 文件并存储了我当前的 PATH 变量。然后每次我使用它时都会将它设置为cmd ,所以它永远不会更新。 您可以在此处查看我创建的问题:https://github.com/nanjingboy/nvmw/issues/5

短篇小说:检查你的HKCU\Software\Microsoft\Command Processor\AutoRun不要使用NVMW包!

我为自动部署做软件打包,有时有些应用程序需要在 %PATH% 中设置它们的文件夹,为此我使用这个 Powershell 脚本。 它会检查该文件夹是否已经存在(因此您不会有重复项)并在需要时将其删除(即静默卸载)。

您使用 ADD-PATH 添加文件夹,使用 REMOVE-PATH 删除文件夹。 很有魅力。

#REQUIRES -Version 3.0

<#
.SYNOPSIS
    A script to add or remove folders to %PATH%
.DESCRIPTION
    It contains 2 functions, one for adding and one for removing. It reads the registry and does the modifications there.
.NOTES
    File Name      : AddRemovePath.ps1
    Author         : Iulian Dita (iulian.dita@gmail.com)
    Prerequisite   : PowerShell V3 over Vista and upper.
    Copyright 2015 - Iulian Dita
.LINK
    Script located at:
    \%server%\dsm2$\Work\Master\Projects532\Extern$
.VERSION
    0.7
.VERSION_HISTORY
    0.1 Initial version
    0.2 Bug fixes
    0.3 Cosmetic fixes, automatic removal of preceding ";"
    0.4 Fixed double entries
    0.5 Kill Explorer and CMD processes before making any modifications
    0.6 Check if folder to be removed already exists in PATH
        Escaping special characters no longer needed for the removal function
    0.7 Cleaned the code and removed some syntax missmatches
        Included the sendmessage function to avoid killing the explorer task
        Used [reges]::escape() to avoid running into troubles with the path-string and -match methode
        Contributed by Maik Krammer
#>

if (-not ("win32.nativemethods" -as [type])) {
    # import sendmessagetimeout from win32
    add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
   IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
   uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
}

$HWND_BROADCAST = [intptr]0xffff;
$WM_SETTINGCHANGE = 0x1a;
$result = [uintptr]::zero

function global:ADD-PATH
{
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)] 
        [string] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $null) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # Get the current search path from the environment keys in the registry.
    $oldPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # See if the new Folder is already in the path.
    if ($oldPath | Select-String -SimpleMatch $Folder){ 
        return 'Folder already within $ENV:PATH' 
    }

    # Set the New Path and add the ; in front
    $newPath=$oldPath+';'+$Folder
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show our results back to the world
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}

function global:REMOVE-PATH {
    [Cmdletbinding()]
    param ( 
        [parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0)]
        [String] $Folder
    )

    # See if a folder variable has been supplied.
    if (!$Folder -or $Folder -eq "" -or $Folder -eq $NULL) { 
        throw 'No Folder Supplied. $ENV:PATH Unchanged'
    }

    # add a leading ";" if missing
    if ($Folder[0] -ne ";") {
        $Folder = ";" + $Folder;
    }

    # Get the Current Search Path from the environment keys in the registry
    $newPath=$(Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path

    # Find the value to remove, replace it with $NULL. If it's not found, nothing will change and you get a message.
    if ($newPath -match [regex]::Escape($Folder)) { 
        $newPath=$newPath -replace [regex]::Escape($Folder),$NULL 
    } else { 
        return "The folder you mentioned does not exist in the PATH environment" 
    }

    # Update the Environment Path
    Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath -ErrorAction Stop

    # Show what we just did
    return 'This is the new PATH content: '+$newPath

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [uintptr]::Zero, "Environment", 2, 5000, [ref]$result)
}


# Use ADD-PATH or REMOVE-PATH accordingly.

#Anything to Add?

ADD-PATH "%_PATH_TO_BE_ADDED%"

#Anything to Remove?

ADD-PATH "%_PATH_TO_BE_REMOVED%"

我没有从头开始创建这个脚本,我在网上找到了片段并根据我的需要进行了调整。

编辑:我稍微更新了代码,您不再需要转义反斜杠或关心前面的 ; 以及其他有用的东西。