Путь системной переменной в командной строке отличается

Я видел разные проблемы, но я сражаюсь с ним целый день, поэтому, пожалуйста, помогите мне:)

Рассказ: у меня есть переменная PATH в панели Системные переменные и cmd. Не удается запустить exe файлы?

Более длинная история: я пытаюсь установить Ruby. Пробовал с разными версиями, но проблема одна и та же: у меня есть мое значение PATH, Ruby есть. НО при использовании его из cmd, рубин не распознается. echo %PATH% дает другое значение от значения в панели переменных среды!

Первое вложение: панель переменных среды:

enter image description here

Значения для переменных пользователя: 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\3.0\bin\x86";"C:\Program Files (x86)\Intel\OpenCL SDK\3.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

Значение для переменных system: 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\3.0\bin\x86";"C:\Program Files (x86)\Intel\OpenCL SDK\3.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 - они все равно.

НО Я запускаю cmd и использую 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\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.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), изменив оба регистра и переменные среды - ничего не работает. Я пробовал добавлять кавычки (") в пути, у которых есть пробелы - нет разницы.

За исключением, если я запустил cmd как администратор и использовал setx PATH "%PATH%;C:\Ruby21\bin"! Затем echo %PATH% возвращает реальный (обновленный) путь, и я могу запустить ruby ТОЛЬКО в этом cmd. Если я закрою его и снова открою его как admin, изменения будут потеряны.

Пожалуйста, дайте мне совет, как с этим справиться? Мне просто нужно запустить Ruby:)

Windows 7 Ultimate, пакет обновления 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\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.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\3.0\bin\x86; C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64; несмотря на, они не похожи на строки, которые я вставил в Путь системных переменных!


Обновление. Я использовал PowerShell и this script, чтобы проверить, есть ли повторение в системных переменных. Я загружаю изображение с результатом. Это довольно странно, что путь именно то, что должно быть, но, как вы можете видеть, в CMD я вижу другую вещь!

enter image description here


Обновление. Сегодня я попытался запустить Ruby из PowerShell - все получилось. Так что кажется, что только CMD не знает, что происходит! И просто напомнить вам - перезагрузка не помогает!:)

Ответ 1

Оказалось, что проблема связана с файлом 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!

Ответ 2

Если ваша системная переменная PATH длиннее некоторого значения, она усекается в командной строке cmd. Согласно этому answer это значение равно 2047. Удалите дубликаты и обрезайте свой путь, вы увидите, что обе переменные будут такими же.

Ответ 3

Когда вы используете операнд SET, он изменяет переменные среды только текущей консоли, это то, для чего это нужно. Чтобы изменить постоянные переменные среды, вы должны использовать команду SETX. И перезагрузите окна. Технически вы не можете перезагрузиться, просто перезапустите все службы, но легко перезагрузитесь.

Ответ 4

Я делаю программную упаковку для автоматического развертывания, а иногда есть приложения, которые нуждаются в настройке своей папки в% PATH%, и для этого я использую эту Powershell script. Он проверяет, есть ли папка уже (так что у вас не будет дубликатов), а также удаляет ее, если необходимо (т.е. Для бесшумной деинсталляции).

Для добавления папки 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 ([email protected])
    Prerequisite   : PowerShell V3 over Vista and upper.
    Copyright 2015 - Iulian Dita
.LINK
    Script located at:
    \\%server%\dsm2$\Work\Master\Projects\29532\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 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%"

Я не создал этот script с нуля, я нашел фрагменты в Интернете и адаптировал их к моим потребностям.

EDIT: я немного обновил код, вам больше не нужно скрывать обратную косую черту или заботиться о ; впереди, а также другие полезные вещи.