如果我在命令行(cmd.exe)中执行set PATH=%PATH%;C:\\Something\\bin
,然后执行echo %PATH%
,我会看到将该字符串添加到PATH中。如果我关闭并重新打开命令行,则该新字符串不在PATH中。
如何永久地从命令行更新所有进程的PATH,而不仅仅是当前进程?
我不想通过转到“系统属性”→“高级”→“环境变量”并在那里更新PATH来实现此目的。
这个命令必须从Java应用程序中执行(请参见我的其他问题)。
您可以使用:
setx PATH "%PATH%;C:\\Something\\bin"
然而,setx
命令会截断存储的字符串到1024字节,可能会破坏路径。
/M
选项将在HKEY_LOCAL_MACHINE
而不是HKEY_CURRENT_USER
中更改PATH
。换句话说,它更改的是系统变量而不是用户的变量。例如:
SETX /M PATH "%PATH%;C:\your path with spaces"
请注意,新的 PATH 在您当前的 cmd.exe
中是不可见的。
但是,如果您在注册表或者新的 cmd.exe
中使用 "set p"
命令,您可以看到新的值。
setx
更改机器的路径而不是用户的路径? - Corey Ogburnsetx
命令时,我收到了错误提示:“默认选项不允许超过'2'次”。如何绕过这个问题? - Nam G VU如何执行此操作的文档可以在MSDN上找到。关键信息如下:
要以编程方式添加或修改系统环境变量,请将其添加到HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment注册表键中,然后广播带有lParam设置为字符串“Environment”的
WM_SETTINGCHANGE
消息。这使得应用程序(例如shell)可以获取您的更新。
请注意,您的应用程序需要具有提升的管理员权限才能修改此键。
您在评论中表示,您很乐意仅修改每个用户的环境。通过编辑HKEY_CURRENT_USER\Environment中的值来实现此目的。与之前一样,请确保广播WM_SETTINGCHANGE
消息。
您应该能够使用JNI注册表类轻松地从Java应用程序中执行此操作。
HKEY_CURRENT_USER\Environment
以避免提升要求。 - kichik我建议不要使用这个命令。
setx PATH "%PATH%;C:\Something\bin"
由于其实现的“特性”,需要修改PATH变量。在许多(大多数?)安装中,该变量将非常长 - setx
将截断存储的字符串为1024个字节,可能会破坏PATH(请参见此处的讨论here)。
(我专门注册以标记此问题,因此缺乏站点声誉,无法直接评论2012年5月2日发布的答案。谢谢beresfordt添加这样的评论)
"""
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
reg query "HKEY_CURRENT_USER\Environment"
。对LOCAL_MACHINE使用"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
。reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZ
。对于包含其他%%变量的路径,请使用REG_EXPAND_SZ
。reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir
。为了参考,对于任何想要通过代码更改路径的人,我引用了一位Delphi程序员在此网页上发布的有用帖子:http://www.tek-tips.com/viewthread.cfm?qid=686382
TonHu (Programmer) 22 Oct 03 17:57 I found where I read the original posting, it's here: http://news.jrsoftware.org/news/innosetup.isx/msg02129....
The excerpt of what you would need is this:
You must specify the string "Environment" in LParam. In Delphi you'd do it this way:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PChar('Environment')));
It was suggested by Jordan Russell, http://www.jrsoftware.org, the author of (a.o.) InnoSetup, ("Inno Setup is a free installer for Windows programs. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.") (I just would like more people to use InnoSetup )
HTH
Runtime.getRuntime().exec("我的命令");
来执行一些CMD命令。 - vale4674