Как постоянно обновлять переменную PATH из cmd? Windows
Если я выполняю set PATH=%PATH%;C:\\Something\\bin
из cmd и затем выполняю echo %PATH%
, я вижу эту строку, добавленную в путь. Если я закрываю и открываю cmd, эта новая строка не находится в PATH. Как я могу постоянно обновлять PATH из cmd для всех процессов в будущем, а не только для текущего процесса?
Я не хочу этого делать, перейдя в System Properties → Advanced → Environment variables и обновляя PATH.
Эта команда должна быть выполнена из приложения java (моя другая question).
Ответы
Ответ 1
Документацию о том, как это сделать, можно найти на MSDN. Экстракт ключа таков:
Чтобы программно добавить или изменить переменные системной среды, добавьте их в раздел реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment, затем передайте WM_SETTINGCHANGE
сообщение с параметром lParam для строки "Окружающая среда". Это позволяет приложениям, таким как оболочка, получать обновления.
Обратите внимание, что для того, чтобы изменить этот ключ, вашему приложению потребуются повышенные права администратора.
В комментариях вы указываете, что с удовольствием изменяете только среду для каждого пользователя. Сделайте это, отредактировав значения в HKEY_CURRENT_USER\Environment. Как и прежде, убедитесь, что вы передали сообщение WM_SETTINGCHANGE
.
Вы должны быть в состоянии сделать это из своего приложения Java достаточно легко, используя классы реестра JNI.
Ответ 2
Вы можете использовать:
setx PATH "%PATH%;C:\\Something\\bin"
Однако setx
усекает сохраненную строку до 1024 байта, что потенциально может привести к повреждению PATH.
/M
изменит PATH
в HKEY_LOCAL_MACHINE
вместо HKEY_CURRENT_USER
. Другими словами, системная переменная, а не пользовательская. Например:
SETX /M PATH "%PATH%;C:\your path with spaces"
Вы должны помнить, что новый PATH не отображается в вашем текущем cmd.exe
.
Но если вы посмотрите в реестре или на новом cmd.exe
с "set p"
, вы увидите новое значение.
Ответ 3
Я не рекомендую использовать команду
setx PATH "%PATH%;C:\Something\bin"
чтобы изменить переменную PATH из-за "функции" ее реализации. На многих (наиболее?) Установках в эти дни переменная будет длинной - setx
усекает сохраненную строку до 1024 байта, потенциально развращая PATH (см. Обсуждение здесь).
(Я специально подписался, чтобы отметить эту проблему, и поэтому мне не хватает репутации сайта, чтобы прямо комментировать ответ, опубликованный 2 мая 2012 года. Благодарю Beresfordt за добавление такого комментария)
Ответ 4
Этот Python- script [*] делает именно это:
"""
Show/Modify/Append registry env-vars (ie `PATH`) and notify Windows-applications to pickup changes.
First attempts to show/modify HKEY_LOCAL_MACHINE (all users), and
if not accessible due to admin-rights missing, fails-back
to HKEY_CURRENT_USER.
Write and Delete operations do not proceed to user-tree if all-users succeed.
Syntax:
{prog} : Print all env-vars.
{prog} VARNAME : Print value for VARNAME.
{prog} VARNAME VALUE : Set VALUE for VARNAME.
{prog} +VARNAME VALUE : Append VALUE in VARNAME delimeted with ';' (i.e. used for `PATH`).
{prog} -VARNAME : Delete env-var value.
Note that the current command-window will not be affected,
changes would apply only for new command-windows.
"""
import winreg
import os, sys, win32gui, win32con
def reg_key(tree, path, varname):
return '%s\%s:%s' % (tree, path, varname)
def reg_entry(tree, path, varname, value):
return '%s=%s' % (reg_key(tree, path, varname), value)
def query_value(key, varname):
value, type_id = winreg.QueryValueEx(key, varname)
return value
def yield_all_entries(tree, path, key):
i = 0
while True:
try:
n,v,t = winreg.EnumValue(key, i)
yield reg_entry(tree, path, n, v)
i += 1
except OSError:
break ## Expected, this is how iteration ends.
def notify_windows(action, tree, path, varname, value):
win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')
print("---%s %s" % (action, reg_entry(tree, path, varname, value)), file=sys.stderr)
def manage_registry_env_vars(varname=None, value=None):
reg_keys = [
('HKEY_LOCAL_MACHINE', r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'),
('HKEY_CURRENT_USER', r'Environment'),
]
for (tree_name, path) in reg_keys:
tree = eval('winreg.%s'%tree_name)
try:
with winreg.ConnectRegistry(None, tree) as reg:
with winreg.OpenKey(reg, path, 0, winreg.KEY_ALL_ACCESS) as key:
if not varname:
for regent in yield_all_entries(tree_name, path, key):
print(regent)
else:
if not value:
if varname.startswith('-'):
varname = varname[1:]
value = query_value(key, varname)
winreg.DeleteValue(key, varname)
notify_windows("Deleted", tree_name, path, varname, value)
break ## Don't propagate into user-tree.
else:
value = query_value(key, varname)
print(reg_entry(tree_name, path, varname, value))
else:
if varname.startswith('+'):
varname = varname[1:]
value = query_value(key, varname) + ';' + value
winreg.SetValueEx(key, varname, 0, winreg.REG_EXPAND_SZ, value)
notify_windows("Updated", tree_name, path, varname, value)
break ## Don't propagate into user-tree.
except PermissionError as ex:
print("!!!Cannot access %s due to: %s" %
(reg_key(tree_name, path, varname), ex), file=sys.stderr)
except FileNotFoundError as ex:
print("!!!Cannot find %s due to: %s" %
(reg_key(tree_name, path, varname), ex), file=sys.stderr)
if __name__=='__main__':
args = sys.argv
argc = len(args)
if argc > 3:
print(__doc__.format(prog=args[0]), file=sys.stderr)
sys.exit()
manage_registry_env_vars(*args[1:])
Ниже приведены примеры использования, предполагая, что он был сохранен в файле с именем setenv.py
где-то в вашем текущем пути.
Обратите внимание, что в этих примерах я не имел прав администратора, поэтому изменения повлияли только на дерево локального реестра:
> REM ## Print all env-vars
> setenv.py
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment:PATH due to: [WinError 5] Access is denied
HKEY_CURRENT_USER\Environment:PATH=...
...
> REM ## Query env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment:PATH due to: [WinError 5] Access is denied
!!!Cannot find HKEY_CURRENT_USER\Environment:PATH due to: [WinError 2] The system cannot find the file specified
> REM ## Set env-var:
> setenv.py PATH C:\foo
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo
> REM ## Append env-var:
> setenv.py +PATH D:\Bar
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment:PATH due to: [WinError 5] Access is denied
---Set HKEY_CURRENT_USER\Environment:PATH=C:\foo;D:\Bar
> REM ## Delete env-var:
> setenv.py -PATH
!!!Cannot access HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment:PATH due to: [WinError 5] Access is denied
---Deleted HKEY_CURRENT_USER\Environment:PATH
[*] Адаптировано из: http://code.activestate.com/recipes/416087-persistent-environment-variables-on-windows/
Ответ 5
Для справочной цели, для тех, кто ищет, как изменить путь через код, я цитирую полезный пост программиста Delphi с этой веб-страницы: http://www.tek-tips.com/viewthread.cfm?qid=686382
TonHu (Программист) 22 окт. 03 17:57 Я нашел, где я прочитал оригинал размещение, это здесь: http://news.jrsoftware.org/news/innosetup.isx/msg02129....
Отрывок из того, что вам нужно, это следующее:
Вы должны указать строку "Окружающая среда" в LParam. В Delphi вы сделайте это так:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PChar('Environment')));
Было предложено Иорданом Расселом, http://www.jrsoftware.org, автор (a.o.) InnoSetup ( "Inno Setup - бесплатный установщик для Программы для Windows. Впервые представленная в 1997 году, Inno Setup сегодня соперничает и даже превосходит многие коммерческие инсталляторы в наборе функций и стабильности." ) (я просто хотел бы, чтобы больше людей использовали InnoSetup)
НТН
Ответ 6
Этот script
http://www.autohotkey.com/board/topic/63210-modify-system-path-gui/
содержит все необходимые вызовы Windows API, которые могут быть реорганизованы для ваших нужд. На самом деле GUI AutoHotkey легко меняет System PATH. Необходимо выполнить роль администратора.
Ответ 7
В корпоративной сети, где пользователь имеет ограниченный доступ и использует портативные приложения, есть следующие трюки командной строки:
- Запросить переменные env пользователя:
reg query "HKEY_CURRENT_USER\Environment"
. Используйте "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
для LOCAL_MACHINE.
- Добавить новую переменную env пользователя:
reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZ
. Используйте REG_EXPAND_SZ
для путей, содержащих другие переменные %%.
- Удалить существующую переменную env:
reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir
.