Если я изменяю или добавляю переменную среды, мне нужно перезапустить командную строку. Могу ли я выполнить команду, которая сделает это без перезапуска CMD?
windows
cmd
environment-variables
Эрик Шуновер
источник
источник
Ответы:
Вы можете перехватить системные переменные окружения с помощью скрипта vbs, но вам нужен скрипт bat для фактического изменения текущих переменных окружения, так что это комбинированное решение.
Создайте файл с именем,
resetvars.vbs
содержащим этот код, и сохраните его по пути:создайте другое имя файла resetvars.bat, содержащее этот код, в том же месте:
Когда вы хотите обновить переменные среды, просто запустите
resetvars.bat
Апологетика :
Две основные проблемы, с которыми я столкнулся при решении этой проблемы:
а. Я не смог найти простой способ экспорта переменных среды из сценария VBS обратно в командную строку, и
б. переменная окружения PATH - это объединение пользовательских и системных переменных PATH.
Я не уверен, каково общее правило для конфликтующих переменных между пользователем и системой, поэтому я решил сделать пользовательскую систему переопределения, за исключением переменной PATH, которая обрабатывается специально.
Я использую странный механизм VBS + BAT + временная BAT, чтобы обойти проблему экспорта переменных из VBS.
Примечание : этот скрипт не удаляет переменные.
Это, вероятно, может быть улучшено.
ADDED
Если вам нужно экспортировать среду из одного окна cmd в другое, используйте этот скрипт (давайте назовем его
exportvars.vbs
):Запуск
exportvars.vbs
в окне вы хотите экспортировать из , а затем переключиться на окно , которое вы хотите экспортировать в и тип:источник
Вот что использует Chocolatey.
https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd
источник
RefreshEnv
обновленные переменные среды в текущем сеансе.Powershell
тоже? Это только кажется, что работаетcmd.exe
для меня.В Windows 7/8/10 вы можете установить Chocolatey, в котором есть встроенный скрипт.
После установки Chocolatey просто введите
refreshenv
.источник
В Windows нет встроенного механизма распространения переменной среды add / change / remove в уже запущенный cmd.exe, либо из другого cmd.exe, либо из «Мой компьютер -> Свойства -> Расширенные настройки -> Переменные среды ».
Если вы изменяете или добавляете новую переменную среды вне области существующей открытой командной строки, вам необходимо либо перезапустить командную строку, либо добавить вручную, используя SET в существующей командной строке.
В последние общепринятый ответ показывает частичное обходным путем вручную обновить все переменные окружения в скрипте. Сценарий обрабатывает сценарий изменения глобальных переменных среды в «Мой компьютер ... Переменные среды», но если переменная среды изменяется в одном cmd.exe, сценарий не распространяет его на другой запущенный cmd.exe.
источник
Я наткнулся на этот ответ, прежде чем в конце концов нашел более простое решение.
Просто перезапустите
explorer.exe
в диспетчере задач.Я не тестировал, но вам также может потребоваться снова открыть командную строку.
Благодарность Тимо Хуовинену здесь: Узел не распознан, хотя и успешно установлен (если это помогло вам, пожалуйста, дайте кредит этого комментария этого человека).
источник
cmd
окно от имени Администратора. Используйте командуtaskkill /f /im explorer.exe && explorer.exe
. Это убьет процесс explorer.exe и перезапустит его.Это работает на Windows 7:
SET PATH=%PATH%;C:\CmdShortcuts
проверил набрав echo% PATH% и все заработало, отлично. также установите, если вы открываете новый cmd, больше не нужны эти надоедливые перезагрузки :)
источник
setx
потому что он наследует текущую среду, которая может иметь переменные, которые были изменены, а не то, что я хочу навсегда. Делая это таким образом, я могу избежать перезапуска консоли, чтобы использовать переменные, и в то же время избежать проблемы, когда они не будут доступны глобально в будущем.Используйте "setx" и перезапустите командную строку
Для этой работы есть инструмент командной строки с именем " setx ". Это для чтения и записи переменных env. Переменные сохраняются после закрытия командного окна.
Он «Создает или изменяет переменные среды в пользовательской или системной среде, не требуя программирования или создания сценариев. Команда setx также извлекает значения ключей реестра и записывает их в текстовые файлы».
Примечание: переменные, созданные или измененные этим инструментом, будут доступны в будущих окнах команд, но не в текущем окне команд CMD.exe. Итак, вы должны перезагрузить.
Если
setx
отсутствует:Или измените реестр
MSDN говорит:
источник
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\VARIABLE
текущая пользовательская среда:HKEY_CURRENT_USER\Environment\VARIABLE
%PATH%
тоsetx
можете сократить это до 1024 байтов! И вот так, его вечер исчезВызов этой функции сработал для меня:
источник
Лучший способ, который я придумал, это просто сделать запрос в реестре. Вот мой пример.
В моем примере я сделал установку с использованием пакетного файла, в который были добавлены новые переменные среды. Мне нужно было что-то сделать, как только установка была завершена, но я не смог запустить новый процесс с этими новыми переменными. Я протестировал создание другого окна обозревателя и перезвонил cmd.exe, и это сработало, но в Vista и Windows 7 проводник запускается только как один экземпляр и обычно как пользователь, вошедший в систему. Это не получится при автоматизации, так как мне нужны права администратора для делать вещи независимо от запуска из локальной системы или от имени администратора на поле. Ограничением является то, что он не обрабатывает такие вещи, как путь, это работает только для простых переменных окружения. Это позволило мне использовать пакет для перехода в каталог (с пробелами) и копирования в файлы, запускаемые .exes и т. Д. Это было написано сегодня из майских ресурсов на stackoverflow.com
Оригинальные Пакетные звонки на новый Пакет:
testenvget.cmd SDROOT (или любая другая переменная)
Также есть другой метод, который я придумал из разных идей. Пожалуйста, смотрите ниже. В основном это приведет к получению самой новой переменной пути из реестра, однако это вызовет ряд проблем, поскольку запрос реестра будет давать переменные сам по себе, что означает, что везде, где есть переменная, это не будет работать, поэтому для борьбы с этой проблемой я в основном удвоить путь. Очень противный Более совершенный метод должен был бы сделать: Set Path =% Path%; C: \ Program Files \ Software .... \
Вне зависимости от того, какой новый пакетный файл, пожалуйста, будьте осторожны.
источник
Самый простой способ добавить переменную в путь без перезагрузки для текущего сеанса - это открыть командную строку и ввести:
и нажмите enter.
чтобы проверить, загружена ли ваша переменная, введите
и нажмите enter. Тем не менее, переменная будет только частью пути до перезагрузки.
источник
Это можно сделать, перезаписав Таблицу среды внутри указанного процесса.
В качестве подтверждения концепции я написал этот пример приложения, которое только что отредактировало одну (известную) переменную среды в процессе cmd.exe:
Пример вывода:
Ноты
Этот подход также будет ограничен ограничениями безопасности. Если цель запускается на более высоком уровне или с более высокой учетной записью (например, 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 происходит сбой).
источник
Переменные среды хранятся в HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet \ Control \ Session Manager \ Environment.
Многие из полезных переменных env, такие как Path, хранятся как REG_SZ. Есть несколько способов получить доступ к реестру, включая REGEDIT:
REGEDIT /E <filename> "HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment"
Вывод начинается с магических чисел. Таким образом, чтобы найти его с помощью команды find, его нужно набрать и перенаправить:
type <filename> | findstr -c:\"Path\"
Так что, если вы просто хотите обновить переменную пути в текущем сеансе команды с помощью того, что находится в системных свойствах, следующий пакетный скрипт работает нормально:
RefreshPath.cmd:
источник
Попробуйте открыть новую командную строку от имени администратора. Это работало для меня на Windows 10. (Я знаю, что это старый ответ, но я должен был поделиться этим, потому что писать сценарий VBS просто для этого абсурдно).
источник
Перезапуск проводника сделал это для меня, но только для новых терминалов cmd.
Терминал, который я установил, мог уже видеть новую переменную Path (в Windows 7).
источник
Смущает то, что есть несколько мест для запуска cmd. В моем случае я запустил cmd из проводника Windows, и переменные среды не изменились, а при запуске cmd из «запуска» (windows key + r) переменные среды были изменены .
В моем случае мне просто пришлось убить процесс проводника Windows из диспетчера задач, а затем снова запустить его из диспетчера задач .
После этого у меня был доступ к новой переменной среды из cmd, который был создан из проводника Windows.
источник
Я использую следующий код в своих пакетных скриптах:
Используя SET после SETX, можно напрямую использовать локальную переменную без перезапуска командного окна. И при следующем запуске будет использоваться переменная окружения.
источник
Мне понравился подход, за которым следовал шоколад, как написано в анонимном ответе труса, так как это чисто пакетный подход. Тем не менее, он оставляет временный файл и некоторые временные переменные валяются. Я сделал более чистую версию для себя.
Сделайте файл
refreshEnv.bat
где-нибудь на вашемPATH
. Обновите вашу консольную среду, выполнивrefreshEnv
.источник
Если это относится только к одной (или нескольким) конкретным переменным, которые вы хотите изменить, я думаю, что самый простой способ - это обходной путь : просто установить в своей среде И в текущем сеансе консоли
У меня есть этот простой пакетный скрипт для изменения моего Maven с Java7 на Java8 (которые оба являются env. Vars). Пакетная папка находится в моей переменной PATH, поэтому я всегда могу вызвать ' j8 ' и в своей консоли, и в среде мой JAVA_HOME var меняется:
j8.bat:
До сих пор я считаю, что это работает лучше и проще. Вы, вероятно, хотите, чтобы это было в одной команде, но ее просто нет в Windows ...
источник
Решение, которым я пользуюсь уже несколько лет:
Изменить: Woops, вот обновленная версия.
источник
Прямого пути нет, как сказал Кев. В большинстве случаев проще создать другую коробку CMD. Более досадно, что запущенные программы также не знают об изменениях (хотя IIRC может быть широковещательным сообщением, которое нужно посмотреть, чтобы получить уведомление о таком изменении).
Хуже было: в старых версиях Windows вам приходилось выходить из системы, а затем снова входить в систему, чтобы учесть изменения ...
источник
Я использую этот скрипт Powershell для добавления в переменную PATH . Я считаю, что с небольшой корректировкой это может сработать и в вашем случае.
источник
Спасибо за публикацию этого вопроса, который весьма интересен, даже в 2019 году (действительно, обновить командную оболочку нелегко, поскольку это единственный экземпляр, как упоминалось выше), поскольку обновление переменных среды в Windows позволяет выполнять многие задачи автоматизации без необходимость вручную перезапустить командную строку.
Например, мы используем это, чтобы разрешить развертывание и настройку программного обеспечения на большом количестве машин, которые мы регулярно переустанавливаем. И я должен признать, что перезапуск командной строки во время развертывания нашего программного обеспечения был бы очень непрактичным и потребовал бы от нас поиска обходных путей, которые не обязательно были бы приятными. Давайте вернемся к нашей проблеме. Мы действуем следующим образом.
1 - у нас есть пакетный скрипт, который в свою очередь вызывает скрипт powershell, подобный этому
[файл: task.cmd] .
CMD
> powershell.exe -executionpolicy unrestricted -File C:\path_here\refresh.ps1
2 - После этого скрипт refresh.ps1 обновляет переменные среды, используя ключи реестра (GetValueNames () и т. Д.). Затем в том же скрипте powershell нам просто нужно вызвать новые переменные среды. Например, в типичном случае, если мы только что установили nodeJS ранее с помощью cmd с помощью тихих команд, после вызова функции мы можем напрямую вызвать npm для установки в том же сеансе определенных пакетов, как показано ниже.
[файл: refresh.ps1]
После завершения сценария powershell сценарий cmd выполняет другие задачи. Теперь следует иметь в виду, что после завершения задачи cmd по-прежнему не имеет доступа к новым переменным среды, даже если сценарий powershell обновил их в своем собственном сеансе. Вот почему мы выполняем все необходимые задачи в скрипте powershell, который, конечно, может вызывать те же команды, что и cmd.
источник
Изменить: это работает, только если изменения среды, которые вы делаете, являются результатом запуска командного файла.
Если пакетный файл начинается с
SETLOCAL
этого, он всегда будет возвращаться к исходной среде при выходе, даже если вы забудете позвонитьENDLOCAL
до выхода из пакета или если он неожиданно прервется.Почти каждый пакетный файл, который я пишу, начинается с того, что
SETLOCAL
в большинстве случаев я не хочу, чтобы побочные эффекты изменений среды сохранялись. В тех случаях, когда я хочу, чтобы определенные изменения переменных среды распространялись за пределы командного файла, мой последнийENDLOCAL
выглядит следующим образом:источник
Чтобы решить эту проблему, я изменил переменную среды, используя ОБА setx и set, а затем перезапустил все экземпляры explorer.exe. Таким образом, любой запущенный процесс будет иметь новую переменную среды.
Мой пакетный скрипт для этого:
Проблема с этим подходом состоит в том, что все окна проводника, которые в данный момент открыты, будут закрыты, что, вероятно, является плохой идеей. Но посмотрите статью Кева, чтобы узнать, почему это необходимо
источник