Есть ли команда для обновления переменных среды из командной строки в Windows?

387

Если я изменяю или добавляю переменную среды, я должен перезапустить командную строку. Есть ли команда, которую я мог бы выполнить, чтобы сделать это без перезапуска CMD?

  • 30
    На самом деле, каждая программа, которая должна их видеть, должна быть перезапущена. При запуске среда копируется в память процесса и, следовательно, больше не связана с определенными системой средами.
  • 12
    Прочитав их, я понял, что ложки нет ;) в реальном мире вы просто перезапустите cmd.
Показать ещё 1 комментарий
Теги:
cmd
environment-variables

28 ответов

126
Лучший ответ

Вы можете захватить переменные системной среды скриптом vbs, но вам нужен сценарий bat, чтобы фактически изменить текущие переменные среды, поэтому это комбинированное решение.

Создайте файл с именем resetvars.vbs содержащий этот код, и сохраните его на пути:

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("System")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")

set oEnv=oShell.Environment("User")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next

path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close

создайте другое имя файла resetvars.bat, содержащее этот код, в том же месте:

@echo off
%~dp0resetvars.vbs
call "%TEMP%\resetvars.bat"

Когда вы хотите обновить переменные среды, просто запустите resetvars.bat


Апологетика:

Две основные проблемы, с которыми я столкнулся с этим решением, были

а. Я не мог найти простой способ экспортировать переменные среды из сценария vbs обратно в командную строку и

б. переменная среды PATH представляет собой конкатенацию пользователя и системных переменных PATH.

Я не уверен, что общее правило для конфликтующих переменных между пользователем и системой, поэтому я решил создать систему переопределения пользователей, за исключением переменной PATH, которая обрабатывается специально.

Я использую странный vbs + bat + временный механизм bat, чтобы обойти проблему экспорта переменных из vbs.

Примечание: этот скрипт не удаляет переменные.

Вероятно, это можно улучшить.

ADDED

Если вам нужно экспортировать среду из одного окна cmd в другой, используйте этот скрипт (позвоните на него exportvars.vbs):

Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)

set oEnv=oShell.Environment("Process")
for each sitem in oEnv 
    oFile.WriteLine("SET " & sitem)
next
oFile.Close

Запуск exportvars.vbs в окне вы хотите экспортировать из, а затем переключиться на окно, которое вы хотите экспортировать, и типа:

"%TEMP%\resetvars.bat"
  • 2
    Возможно, вы можете избежать временного файла, используя конструкцию DO tokens = 1, * "%% c IN ('resetvars.vbs') для FOR / F
  • 2
    Как я уже сказал в своем ответе «или, вручную добавьте, используя SET в существующей командной строке». это то, что это эффективно делает. Хороший ответ, хотя.
Показать ещё 11 комментариев
74

Вот что использует Chocolatey.

https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd

@echo off
::
:: RefreshEnv.cmd
::
:: Batch file to read environment variables from registry and
:: set session variables to these values.
::
:: With this batch file, there should be no need to reload command
:: environment every time you want environment changes to propagate

echo | set /p dummy="Reading environment variables from registry. Please wait... "

goto main

:: Set one environment variable from registry key
:SetFromReg
    "%WinDir%\System32\Reg" QUERY "%~1" /v "%~2" > "%TEMP%\_envset.tmp" 2>NUL
    for /f "usebackq skip=2 tokens=2,*" %%A IN ("%TEMP%\_envset.tmp") do (
        echo/set %~3=%%B
    )
    goto :EOF

:: Get a list of environment variables from registry
:GetRegEnv
    "%WinDir%\System32\Reg" QUERY "%~1" > "%TEMP%\_envget.tmp"
    for /f "usebackq skip=2" %%A IN ("%TEMP%\_envget.tmp") do (
        if /I not "%%~A"=="Path" (
            call :SetFromReg "%~1" "%%~A" "%%~A"
        )
    )
    goto :EOF

:main
    echo/@echo off >"%TEMP%\_env.cmd"

    :: Slowly generating final file
    call :GetRegEnv "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" >> "%TEMP%\_env.cmd"
    call :GetRegEnv "HKCU\Environment">>"%TEMP%\_env.cmd" >> "%TEMP%\_env.cmd"

    :: Special handling for PATH - mix both User and System
    call :SetFromReg "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" Path Path_HKLM >> "%TEMP%\_env.cmd"
    call :SetFromReg "HKCU\Environment" Path Path_HKCU >> "%TEMP%\_env.cmd"

    :: Caution: do not insert space-chars before >> redirection sign
    echo/set Path=%%Path_HKLM%%;%%Path_HKCU%% >> "%TEMP%\_env.cmd"

    :: Cleanup
    del /f /q "%TEMP%\_envset.tmp" 2>nul
    del /f /q "%TEMP%\_envget.tmp" 2>nul

    :: Set these variables
    call "%TEMP%\_env.cmd"

    echo | set /p dummy="Done"
    echo .
  • 46
    +1 Если у вас установлен Chocolatey, вы можете просто запустить RefreshEnv чтобы получить обновленные переменные среды в текущем сеансе.
  • 2
    Это невероятно полезная часть служебного программного обеспечения, большое спасибо за обмен.
Показать ещё 3 комментария
57

По дизайну не существует встроенного механизма для Windows, чтобы распространять переменную среды add/change/remove на уже запущенный cmd.exe либо из другого cmd.exe, либо из "My Компьютер → Свойства → Дополнительные параметры → Переменные среды".

Если вы изменяете или добавляете новую переменную среды за пределы существующей открытой командной строки, вам нужно либо перезапустить командную строку, либо вручную добавить с помощью SET в существующую командную строку.

последний принятый ответ показывает частичную обработку, вручную обновляя все переменные среды в script. script обрабатывает прецедент изменения переменных среды во всем мире в "My Computer... Environment Variables", но если переменная среды изменяется в одном cmd.exe, то script не будет распространять ее на другой запущенный cmd.exe.

  • 0
    Если у кого-то есть рабочее решение этой проблемы, я периодически проверяю и могу изменить принятый ответ.
  • 0
    Это не должен быть принятый ответ просто потому, что он не отвечает на заданный вопрос. этот вопрос должен оставаться без принятого ответа до тех пор, пока он не будет найден.
Показать ещё 4 комментария
35

Это работает в Windows 7: SET PATH=%PATH%;C:\CmdShortcuts

проверено путем ввода echo% PATH%, и это сработало, отлично. также устанавливаются, если вы открываете новый cmd, больше не нужно для этих отвратительных перезагрузок:)

  • 1
    Не работает для "нового cmd" для меня (Win7 x64). Смотрите скринвидео
  • 26
    Это не решает вопрос, задаваемый, и не должен. Первоначальный вопрос заключается в том, как обновить переменную среды до значения, которое было установлено вне этого терминала.
Показать ещё 1 комментарий
33

В окнах 7/8/10 вы можете установить Chocolatey, у которого есть script для этого встроенного.

После установки Chocolatey просто введите "refreshenv" без кавычек.

  • 0
    это правильный ответ, было бы приятно услышать от парня, который проголосовал против
  • 0
    Только что проверил, полностью работает на моей коробке Windows10
Показать ещё 6 комментариев
33

Я наткнулся на этот ответ, прежде чем найти более легкое решение.

Просто перезапустите explorer.exe в диспетчере задач.

Я не тестировал, но вам также может понадобиться повторно открыть командную строку.

Кредит Timo Huovinen здесь: Node не признан, хотя успешно установлен (если это помогло вам, пожалуйста, дайте этому человеку комментарий кредит).

  • 0
    Я приехал сюда, потому что пытался добавить внешний инструмент в Visual Studio, чтобы я мог открыть командную строку в корне моего решения, как описано в этом блоге: neverindoubtnet.blogspot.com/2012/10/… ... и У меня были похожие проблемы ... Я пытался заставить "git" появляться в моей переменной пути. Я добавил каталоги git в переменную PATH, но тогда они не будут отображаться в командной строке, которую я открою из Visual Studio. Простым решением было перезапустить Visual Studio. Тогда новые дополнения к переменной PATH были видны в cmd.
  • 0
    хорошее решение ... спасибо
Показать ещё 7 комментариев
23

Используйте "setx" и перезапустите приглашение cmd

Для этого задания используется инструмент командной строки с именем setx". Он для чтения и записи переменных env. Переменные сохраняются после закрытия командного окна.

It "Создает или изменяет переменные среды в пользовательской или системной среде, не требуя программирования или скриптов. Команда setx также извлекает значения ключей реестра и записывает их в текстовые файлы. "

Примечание: переменные, созданные или измененные этим инструментом, будут доступны в будущих командных окнах, но не в текущем командном окне CMD.exe. Итак, вы должны перезапустить.

Если setx отсутствует:


Или изменить реестр

MSDN говорит:

Чтобы программно добавить или изменить переменные системной среды, добавьте их к HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\сессии Manager\Environment, затем передайте WM_SETTINGCHANGEсообщение с lParam установлено в строку " Среда".

Это позволяет приложениям, таким как оболочка, получать обновления.

  • 1
    Не могли бы вы рассказать о том, как использовать setx для чтения переменных окружения? Я изучил различные документы и просто не вижу их. : - /
  • 2
    setx VARIABLE -k "HKEY_LOCAL_MACHINE \ Software \ Microsoft \ WindowsNT \ CurrentVersion \ CurrentVersion" echo% VARIABLE%
Показать ещё 10 комментариев
13

Вызов этой функции сработал у меня:

VOID Win32ForceSettingsChange()
{
    DWORD dwReturnValue;
    ::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
}
  • 0
    +1, но это работает только для программ с графическим интерфейсом.
  • 8
    и не все программы слушают это сообщение (фактически большинство из них, вероятно, не делают)
Показать ещё 1 комментарий
10

Лучший метод, который я придумал, - это просто выполнить запрос реестра. Вот мой пример.

В моем примере я сделал установку с использованием Batch файла, который добавил новые переменные среды. Мне нужно было сделать что-то с этим, как только установка была завершена, но не смог создать новый процесс с этими новыми переменными. Я протестировал создание другого окна проводника и вызвал его обратно в cmd.exe, и это сработало, но в Vista и Windows 7 Explorer работает только как один экземпляр и обычно, как и пользователь, который входит в систему. Это может завершиться неудачей с автоматизацией, так как мне нужны мои учетные записи администратора делать что-то независимо от работы из локальной системы или администратора в поле. Ограничением на это является то, что он не обрабатывает такие вещи, как путь, это работает только с простыми переменными окружения. Это позволило мне использовать пакет, чтобы перейти в каталог (с пробелами) и скопировать в файлы, запускаемые .exe и т.д. Это было написано сегодня из возможных ресурсов на stackoverflow.com

Orginal Batch вызывает новую партию:

testenvget.cmd SDROOT (или любая переменная)

@ECHO OFF
setlocal ENABLEEXTENSIONS
set keyname=HKLM\System\CurrentControlSet\Control\Session Manager\Environment
set value=%1
SET ERRKEY=0

REG QUERY "%KEYNAME%" /v "%VALUE%" 2>NUL| FIND /I "%VALUE%"
IF %ERRORLEVEL% EQU 0 (
ECHO The Registry Key Exists 
) ELSE (
SET ERRKEY=1
Echo The Registry Key Does not Exist
)

Echo %ERRKEY%
IF %ERRKEY% EQU 1 GOTO :ERROR

FOR /F "tokens=1-7" %%A IN ('REG QUERY "%KEYNAME%" /v "%VALUE%" 2^>NUL^| FIND /I "%VALUE%"') DO (
ECHO %%A
ECHO %%B
ECHO %%C
ECHO %%D
ECHO %%E
ECHO %%F
ECHO %%G
SET ValueName=%%A
SET ValueType=%%B
SET C1=%%C
SET C2=%%D
SET C3=%%E
SET C4=%%F
SET C5=%%G
)

SET VALUE1=%C1% %C2% %C3% %C4% %C5%
echo The Value of %VALUE% is %C1% %C2% %C3% %C4% %C5%
cd /d "%VALUE1%"
pause
REM **RUN Extra Commands here**
GOTO :EOF

:ERROR
Echo The the Enviroment Variable does not exist.
pause
GOTO :EOF

Также есть другой метод, который я придумал из разных идей. См. Ниже. Это, в основном, приведет к новой переменной пути из реестра, однако это вызовет ряд проблем, связанных с тем, что запрос реестра будет давать переменные сами по себе, а значит, везде есть переменная, это не сработает, поэтому для борьбы с этой проблемой я в основном удваивают путь. Очень противно. Более предпочтительный метод:   Set Path =% Path%; C:\Program Files\Software....\

Независимо от того, что это новый пакетный файл, будьте осторожны.

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
set org=%PATH%
for /f "tokens=2*" %%A in ('REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path ^|FIND /I "Path"') DO (
SET path=%%B
)
SET PATH=%org%;%PATH%
set path
7

Это можно сделать, перезаписав таблицу окружения в пределах самого указанного процесса.

В качестве доказательства концепции я написал это примерное приложение, которое только что редактировало одну (известную) переменную среды в процессе cmd.exe:

typedef DWORD (__stdcall *NtQueryInformationProcessPtr)(HANDLE, DWORD, PVOID, ULONG, PULONG);

int __cdecl main(int argc, char* argv[])
{
    HMODULE hNtDll = GetModuleHandleA("ntdll.dll");
    NtQueryInformationProcessPtr NtQueryInformationProcess = (NtQueryInformationProcessPtr)GetProcAddress(hNtDll, "NtQueryInformationProcess");

    int processId = atoi(argv[1]);
    printf("Target PID: %u\n", processId);

    // open the process with read+write access
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, 0, processId);
    if(hProcess == NULL)
    {
        printf("Error opening process (%u)\n", GetLastError());
        return 0;
    }

    // find the location of the PEB
    PROCESS_BASIC_INFORMATION pbi = {0};
    NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    if(status != 0)
    {
        printf("Error ProcessBasicInformation (0x%8X)\n", status);
    }
    printf("PEB: %p\n", pbi.PebBaseAddress);

    // find the process parameters
    char *processParamsOffset = (char*)pbi.PebBaseAddress + 0x20; // hard coded offset for x64 apps
    char *processParameters = NULL;
    if(ReadProcessMemory(hProcess, processParamsOffset, &processParameters, sizeof(processParameters), NULL))
    {
        printf("UserProcessParameters: %p\n", processParameters);
    }
    else
    {
        printf("Error ReadProcessMemory (%u)\n", GetLastError());
    }

    // find the address to the environment table
    char *environmentOffset = processParameters + 0x80; // hard coded offset for x64 apps
    char *environment = NULL;
    ReadProcessMemory(hProcess, environmentOffset, &environment, sizeof(environment), NULL);
    printf("environment: %p\n", environment);

    // copy the environment table into our own memory for scanning
    wchar_t *localEnvBlock = new wchar_t[64*1024];
    ReadProcessMemory(hProcess, environment, localEnvBlock, sizeof(wchar_t)*64*1024, NULL);

    // find the variable to edit
    wchar_t *found = NULL;
    wchar_t *varOffset = localEnvBlock;
    while(varOffset < localEnvBlock + 64*1024)
    {
        if(varOffset[0] == '\0')
        {
            // we reached the end
            break;
        }
        if(wcsncmp(varOffset, L"ENVTEST=", 8) == 0)
        {
            found = varOffset;
            break;
        }
        varOffset += wcslen(varOffset)+1;
    }

    // check to see if we found one
    if(found)
    {
        size_t offset = (found - localEnvBlock) * sizeof(wchar_t);
        printf("Offset: %Iu\n", offset);

        // write a new version (if the size of the value changes then we have to rewrite the entire block)
        if(!WriteProcessMemory(hProcess, environment + offset, L"ENVTEST=def", 12*sizeof(wchar_t), NULL))
        {
            printf("Error WriteProcessMemory (%u)\n", GetLastError());
        }
    }

    // cleanup
    delete[] localEnvBlock;
    CloseHandle(hProcess);

    return 0;
}

Пример вывода:

>set ENVTEST=abc

>cppTest.exe 13796
Target PID: 13796
PEB: 000007FFFFFD3000
UserProcessParameters: 00000000004B2F30
environment: 000000000052E700
Offset: 1528

>set ENVTEST
ENVTEST=def

Примечания

Этот подход также будет ограничен ограничениями безопасности. Если цель запущена на более высокой отметке или более высокой учетной записи (например, SYSTEM), у нас не будет разрешения на редактирование ее памяти.

Если вы хотите сделать это в 32-битном приложении, то жестко закодированные смещения выше будут меняться на 0x10 и 0x48 соответственно. Эти смещения можно найти, выгружая структуры _PEB и _RTL_USER_PROCESS_PARAMETERS в отладчике (например, в WinDbg dt _PEB и dt _RTL_USER_PROCESS_PARAMETERS)

Чтобы изменить концептуальную концепцию на то, что требуется OP, она просто перечислит текущие переменные системы и пользовательских окружений (например, задокументированные ответом @tsadok) и напишет всю таблицу окружения в память целевого процесса.

Изменить: размер блока среды также сохраняется в структуре _RTL_USER_PROCESS_PARAMETERS, но память выделяется в куче процесса. Поэтому из внешнего процесса у нас не было бы возможности изменять его размер и увеличивать его. Я играл с помощью VirtualAllocEx, чтобы выделить дополнительную память в целевом процессе для хранения среды, и смог установить и прочитать совершенно новую таблицу. К сожалению, любая попытка изменить среду с помощью обычных средств будет сбой и сбой, поскольку адрес больше не указывает на кучу (он сбой в RtlSizeHeap).

5

Переменные среды хранятся в HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\Session Manager\Environment.

Многие полезные env vars, такие как Path, сохраняются как REG_SZ. Существует несколько способов доступа к реестру, включая REGEDIT:

REGEDIT /E &lt;filename&gt; "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"код >

Выход начинается с магических чисел. Поэтому, чтобы искать его с помощью команды find, ее нужно набирать и перенаправлять: type <filename> | findstr -c:\"Path\"

Итак, если вы просто хотите обновить переменную пути в текущем командном сеансе с тем, что в свойствах системы следующая партия script отлично работает:

RefreshPath.cmd:


    @echo off

    REM This solution requests elevation in order to read from the registry.

    if exist %temp%\env.reg del %temp%\env.reg /q /f

    REGEDIT /E %temp%\env.reg "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"

    if not exist %temp%\env.reg (
       echo "Unable to write registry to temp location"
       exit 1
       )

    SETLOCAL EnableDelayedExpansion

    for /f "tokens=1,2* delims==" %%i in ('type %temp%\env.reg ^| findstr -c:\"Path\"=') do (
       set upath=%%~j
       echo !upath:\\=\! >%temp%\newpath
       )

     ENDLOCAL

     for /f "tokens=*" %%i in (%temp%\newpath) do set path=%%i
  • 5
    Переменные среды не хранятся в реестре. В реестре хранится шаблон , из которого такие программы, как Windows Explorer, (заново) создают свои переменные среды при получении соответствующего уведомления . Фактические переменные среды являются для каждого процесса и хранятся в собственном адресном пространстве каждого процесса, первоначально наследуемого от его родительского процесса и впоследствии модифицируемого по прихоти процесса.
4

Путаница может заключаться в том, что есть несколько мест для запуска cmd. В моем случае я запустил cmd из Windows Explorer, а переменные не изменились, когда при запуске cmd из "run" (ключ Windows + r) изменена переменная окружения .

В моем случае мне просто пришлось убить процесс проводника Windows из диспетчера задач, а затем снова перезапустить его из диспетчера задач.

Как только я сделал это, у меня был доступ к новой переменной среды из cmd, которая была порождена из обозревателя Windows.

4

Самый простой способ добавить переменную к пути без перезагрузки для текущего сеанса - открыть командную строку и ввести:

PATH=(VARIABLE);%path%

и нажмите enter.

чтобы проверить, загружена ли ваша переменная, введите

PATH

и нажмите enter. Однако переменная будет только частью пути до перезагрузки.

4

Попробуйте открыть новую командную строку в качестве администратора. Это работало для меня в Windows 10. (Я знаю, что это старый ответ, но мне пришлось поделиться этим, потому что писать VBS script просто для этого абсурдно).

3

Перезапуск explorer сделал это для меня, но только для новых CMD терминалов.

Терминал, на который я установил путь, мог видеть новую переменную Path уже (в Windows 7).

taskkill /f /im explorer.exe && explorer.exe
3

Мне понравился подход, за которым последовали шоколадные, как указано в анонимном трусовом ответе, так как это чистый пакетный подход. Однако он оставляет временный файл и некоторые временные переменные. Я сделал для себя более чистую версию.

Сделайте файл refreshEnv.bat где-нибудь на вашем PATH. Обновите среду консоли, выполнив refreshEnv.

@ECHO OFF
REM Source found on https://github.com/DieterDePaepe/windows-scripts
REM Please share any improvements made!

REM Code inspired by http://stackoverflow.com/questions/171588/is-there-a-command-to-refresh-environment-variables-from-the-command-prompt-in-w

IF [%1]==[/?] GOTO :help
IF [%1]==[/help] GOTO :help
IF [%1]==[--help] GOTO :help
IF [%1]==[] GOTO :main

ECHO Unknown command: %1
EXIT /b 1 

:help
ECHO Refresh the environment variables in the console.
ECHO.
ECHO   refreshEnv       Refresh all environment variables.
ECHO   refreshEnv /?        Display this help.
GOTO :EOF

:main
REM Because the environment variables may refer to other variables, we need a 2-step approach.
REM One option is to use delayed variable evaluation, but this forces use of SETLOCAL and
REM may pose problems for files with an '!' in the name.
REM The option used here is to create a temporary batch file that will define all the variables.

REM Check to make sure we don't overwrite an actual file.
IF EXIST %TEMP%\__refreshEnvironment.bat (
  ECHO Environment refresh failed!
  ECHO.
  ECHO This script uses a temporary file "%TEMP%\__refreshEnvironment.bat", which already exists. The script was aborted in order to prevent accidental data loss. Delete this file to enable this script.
  EXIT /b 1
)

REM Read the system environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM Read the user environment variables from the registry.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment`) DO (
  REM /I -> ignore casing, since PATH may also be called Path
  IF /I NOT [%%I]==[PATH] (
    ECHO SET %%I=%%K>>%TEMP%\__refreshEnvironment.bat
  )
)

REM PATH is a special variable: it is automatically merged based on the values in the
REM system and user variables.
REM Read the PATH variable from the system and user environment variables.
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH`) DO (
  ECHO SET PATH=%%K>>%TEMP%\__refreshEnvironment.bat
)
FOR /F "usebackq tokens=1,2,* skip=2" %%I IN (`REG QUERY HKCU\Environment /v PATH`) DO (
  ECHO SET PATH=%%PATH%%;%%K>>%TEMP%\__refreshEnvironment.bat
)

REM Load the variable definitions from our temporary file.
CALL %TEMP%\__refreshEnvironment.bat

REM Clean up after ourselves.
DEL /Q %TEMP%\__refreshEnvironment.bat

ECHO Environment successfully refreshed.
  • 0
    это также для% CLIENTNAME%? - у меня не сработало - stackoverflow.com/questions/37550160/…
  • 0
    % CLIENTNAME% недоступен в моей среде, и, прочитав ваш вопрос, я предположу, что это что-то заданное внешним процессом. (Когда процесс запускает дочерний процесс, он может настроить среду для этого дочернего процесса.) Поскольку он не является частью реальных переменных среды, он не будет обновляться этим сценарием.
Показать ещё 3 комментария
3

просто перезапустите explorer.exe → протестирован на win 8 X64

  • 0
    Это не отвечает на вопрос ... хотя фактически обновляет переменные окружения, это для одного полностью перебором (достаточно перезапустить cmd.exe) и, во-вторых, не для команды, которая позволяет сохранить текущий сеанс cmd ...
  • 0
    Зачем голосовать вниз? Вопрос: есть ли команда для обновления переменных среды из командной строки в Windows? Закрытие всех окон проводника и повторное открытие делает трюк, так как Windows Vista.
Показать ещё 1 комментарий
3

Я использую следующий код в своих командных скриптах:

if not defined MY_ENV_VAR (
    setx MY_ENV_VAR "VALUE" > nul
    set MY_ENV_VAR=VALUE
)
echo %MY_ENV_VAR%

Используя SET после SETX, можно использовать "локальную" переменную напрямую без перезапуска окна команд. И при следующем запуске будет использоваться переменная среды.

  • 0
    Пока я получаю то, что вы сделали, скорее всего, он хочет что-то для параллельных сценариев, один сценарий устанавливает глобальные переменные, а другой читает их. В противном случае, нет смысла привлекать setx, set будет достаточно.
2

Сначала установите choco:

  • если используется cmd @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

  • при использовании powershell Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Затем вы можете запустить refreshenv. Он работает как на cmd, так и на powershell.

  • 0
    @Stephan, обновил ответ.
  • 0
    Не работает с PowerShell для меня.
Показать ещё 1 комментарий
2

Если это касается только одного (или нескольких) конкретных vars, которые вы хотите изменить, я думаю, что самый простой способ - это обходной путь: просто установите в своей среде И в текущем сеансе консоли

  • Set поместит var в ваш текущий сеанс
  • SetX поместит var в среду, но НЕ в ваш текущий сеанс

У меня есть эта простая партия script, чтобы сменить мой Maven с Java7 на Java8 (которые являются как env. vars) Пакетная папка находится в моем PATH var, поэтому я всегда могу позвонить ' j8 'и внутри моей консоли и в среде меня изменяет мой JAVA_HOME var:

j8.bat:

@echo off
set JAVA_HOME=%JAVA_HOME_8%
setx JAVA_HOME "%JAVA_HOME_8%"

До сих пор я считаю, что это работает лучше всего и проще всего. Вероятно, вы хотите, чтобы это была одна команда, но ее просто нет в Windows...

1

Я использую эту Powershell script для добавления в переменную PATH. С небольшой настройкой он может работать и в вашем случае, я тоже верю.

#REQUIRES -Version 3.0

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?

#Anything to Remove?

REMOVE-PATH "%_installpath_bin%"
1

Нет прямого пути, как сказал Кев. В большинстве случаев проще создать еще один CMD-блок. Более раздражающе, запущенные программы также не знают об изменениях (хотя в МИРК может быть широковещательное сообщение, чтобы следить за тем, чтобы получать уведомления об этом изменении).

Это было хуже: в старых версиях Windows вам пришлось выйти из системы, а затем вернуться назад, чтобы принять во внимание изменения...

0

У меня была одна и та же проблема, но эти предложения не работали. Я запустил программу защиты от вредоносных программ и обнаружил, что PUP (потенциально нежелательная программа) на моем компьютере пришлось перезагрузить компьютер, чтобы удалить его. Теперь я могу найти обновления. Вредоносная программа, которую я использовал, была суперинтенсивной.

0

Чтобы решить эту проблему, я изменил переменную среды с помощью BOTH setx и установил, а затем перезапустил все экземпляры explorer.exe. Таким образом, любой последующий процесс будет иметь новую переменную среды.

Моя партия script для этого:

setx /M ENVVAR "NEWVALUE"
set ENVVAR="NEWVALUE"

taskkill /f /IM explorer.exe
start explorer.exe >nul
exit

Проблема с этим подходом заключается в том, что все окна браузера, которые в настоящее время открыты, будут закрыты, что, вероятно, является плохой идеей. Но посмотрите сообщение Kev, чтобы узнать, почему это необходимо.

0

Изменить: это работает только в том случае, если изменения среды, которые вы делаете, являются результатом запуска пакетного файла.

Если командный файл начинается с SETLOCAL, он всегда будет возвращаться к исходной среде при выходе, даже если вы забудете позвонить ENDLOCAL до выхода партии или неожиданно прервать ее.

Почти каждый командный файл, который я пишу, начинается с SETLOCAL, так как в большинстве случаев я не хочу, чтобы побочные эффекты изменений среды оставались. В тех случаях, когда я хочу, чтобы некоторые переменные переменных среды распространялись вне пакетного файла, мой последний ENDLOCAL выглядит следующим образом:

ENDLOCAL & (
  SET RESULT1=%RESULT1%
  SET RESULT2=%RESULT2%
)
0

нет, я так не думаю... вы можете установить их вручную. Поэтому вы можете поместить их в пакетный файл или что-то в этом роде.

возможно, может сделать служебную программу / script (если ее еще нет), которая запрашивает реестр и устанавливает текущую среду, которая будет той же

-3

Просто введите "# -r" (без кавычек # с опцией -r) в вашем терминале. И вы все настроены на пути по умолчанию:)

  • 0
    Это не работает как поведение по умолчанию, если есть какое-то приложение, которое делает это для вас / запускается с помощью приведенной выше команды, то есть полное решение. Ответ должен быть обновлен, если так.
  • 0
    '#' is not recognized as an internal or external command, operable program or batch file
Показать ещё 2 комментария
-3

Или вы можете просто сделать это вручную через

Чтобы просмотреть или изменить переменные среды: щелкните правой кнопкой мыши Мой компьютер и затем нажмите "Свойства". Перейдите на вкладку "Дополнительно". Щелкните Environment переменные. Выберите один из следующих вариантов: для пользователя или системная переменная: нажмите "Создать", чтобы добавить новое имя и значение переменной. Нажмите существующую переменную, а затем нажмите "Изменить", чтобы изменить его имя или значение. Щелкните существующую переменную и нажмите "Удалить", чтобы удалить ее. http://support.microsoft.com/kb/310519

Переменные среды Windows XP

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\Documents and Settings\All Users
%APPDATA%   C:\Documents and Settings\{username}\Application Data
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Documents and Settings\{username}
%LOCALAPPDATA%  Not available
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.WSF;.WSH
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    The Windows directory, usually C:\Windows, formerly C:\WINNT
%TEMP% and %TMP%    C:\Documents and Settings\{username}\Local Settings\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Documents and Settings\{username}
%WINDIR%    C:\Windows
%PUBLIC%    
%PROGRAMDATA%   Only available in Windows Vista and newer versions
%PSModulePath%  

Переменные среды Windows 7

%ALLUSERSPROFILE% (%PROGRAMDATA%)   C:\ProgramData
%APPDATA%   C:\Users\{username}\AppData\Roaming
%COMPUTERNAME%  {computername}
%COMMONPROGRAMFILES%    C:\Program Files\Common Files
%COMMONPROGRAMFILES(x86)%   C:\Program Files (x86)\Common Files
%COMSPEC%   C:\Windows\System32\cmd.exe
%HOMEDRIVE% C:
%HOMEPATH%  \Users\{username}
%LOCALAPPDATA%  C:\Users\{username}\AppData\Local
%LOGONSERVER%   \\{domain_logon_server}
%PATH%  C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;{plus program paths}
%PATHEXT%   .com;.exe;.bat;.cmd;.vbs;.vbe;.js;.jse;.wsf;.wsh;.msc
%PROGRAMFILES%  C:\Program Files
%PROGRAMFILES(X86)% C:\Program Files (x86) (only in 64-bit version)
%PROMPT%    Code for current command prompt format. Code is usually $P$G
%SystemDrive%   C:
%SystemRoot%    C:\Windows
%TEMP% and %TMP%    C:\Users\{username}\AppData\Local\Temp
%USERDOMAIN%    {userdomain}
%USERNAME%  {username}
%USERPROFILE%   C:\Users\{username}
%WINDIR%    C:\Windows
%PUBLIC%    C:\Users\Public
%PROGRAMDATA%   C:\ProgramData
%PSModulePath%  %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules\

http://www.binbert.com/blog/2010/09/default-environment-variable-values-of-windows-7-xp/

надеюсь, что это поможет.

  • 0
    Не отвечает на вопрос.
  • 0
    Изменения не влияют на программы, которые уже запущены. ОП хочет, чтобы они.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню