Si j'exécute set PATH=%PATH%;C:\\Something\\bin
à partir de cmd puis exécute echo %PATH%
, cette chaîne est ajoutée au chemin. Si je ferme et ouvre cmd, cette nouvelle chaîne n'est pas dans PATH. Comment puis-je mettre à jour de manière permanente PATH à partir de cmd pour tous les processus à venir, pas seulement pour le processus actuel? Je ne veux pas faire cela en allant dans Propriétés système -> Avancé -> Variables d'environnement et là, mettez à jour PATH.
Cette commande doit être exécutée à partir de Java application (mon autre question ).
La documentation sur la procédure à suivre est disponible sur MSDN . L'extrait clé est la suivante:
Pour ajouter ou modifier par programme des variables d'environnement système, ajoutez-les à la clé de registre HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment , puis diffusez une -
WM_SETTINGCHANGE
message avec lParam défini sur la chaîne "Environment". Cela permet aux applications, telles que Shell, de récupérer vos mises à jour.
Notez que votre application aura besoin de droits d’administrateur élevés pour pouvoir modifier cette clé.
Vous indiquez dans les commentaires que vous seriez heureux de modifier uniquement l'environnement par utilisateur. Pour ce faire, modifiez les valeurs dans HKEY_CURRENT_USER\Environment . Comme précédemment, assurez-vous de diffuser un message WM_SETTINGCHANGE
.
Vous devriez pouvoir le faire depuis votre application Java en utilisant assez facilement les classes de registre JNI.
Vous pouvez utiliser:
setx PATH "%PATH%;C:\\Something\\bin"
Cependant, setx
tronquera la chaîne stockée à 1024 octets, ce qui pourrait endommager le PATH.
/M
modifiera la PATH
dans HKEY_LOCAL_MACHINE
au lieu de HKEY_CURRENT_USER
. En d'autres termes, une variable système, au lieu de l'utilisateur. Par exemple:
SETX /M PATH "%PATH%;C:\your path with spaces"
N'oubliez pas que le nouveau PATH n'est pas visible dans votre cmd.exe
actuel.
Mais si vous regardez dans le registre ou sur un nouveau cmd.exe
avec "set p"
, vous pouvez voir la nouvelle valeur.
Je mets en garde contre l'utilisation de la commande
setx PATH "%PATH%;C:\Something\bin"
modifier la variable PATH en raison d'une "fonctionnalité" de son implémentation. La plupart du temps, la variable sera longue sur la plupart des installations (la plupart?) - setx
tronquera la chaîne stockée sur 1024 octets, altérant potentiellement le PATH (voir la discussion ici ).
( Je me suis spécifiquement inscrit pour signaler ce problème et il me manque donc la réputation du site pour commenter directement la réponse publiée le 2 mai 2012. Je remercie beresfordt d'avoir ajouté un tel commentaire )
Ce script Python [*] fait exactement cela:
"""
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:])
Vous trouverez ci-dessous quelques exemples d'utilisation, en supposant qu'il ait été enregistré dans un fichier nommé setenv.py
quelque part dans votre chemin actuel. Notez que dans ces exemples, i ne possédait pas de droits d'administrateur , de sorte que les modifications ne concernaient que l'arborescence de registre de mon utilisateur local:
> 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
[*] Adapté de: http://code.activestate.com/recipes/416087-persistent-environment-variables-on-windows/
Dans un réseau d'entreprise, où l'utilisateur n'a qu'un accès limité et utilise des applications portables, voici quelques astuces en ligne de commande:
reg query "HKEY_CURRENT_USER\Environment"
. Utilisez "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
pour LOCAL_MACHINE.reg add "HKEY_CURRENT_USER\Environment" /v shared_dir /d "c:\shared" /t REG_SZ
. Utilisez REG_EXPAND_SZ
pour les chemins contenant d'autres variables %%.reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir
.À titre de référence, pour ceux qui cherchent à changer le chemin via du code, je cite un message utile rédigé par un programmeur Delphi à partir de cette page Web: http://www.tek-tips.com/viewthread.cfm? qid = 686382
TonHu (Programmeur) 22 Oct 03 17:57 J'ai trouvé où j'avais lu le message original, il est ici: http://news.jrsoftware.org/news/innosetup.isx/msg02129 ....
Voici l'extrait de ce dont vous auriez besoin:
Vous devez spécifier la chaîne "Environment" dans LParam. À Delphi, vous le feriez comme suit:
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, Integer(PChar('Environment')));
Il a été suggéré par Jordan Russell, http://www.jrsoftware.org , auteur de (entre autres) InnoSetup, "Inno Setup est un programme d'installation gratuit pour les programmes Windows. Introduit pour la première fois en 1997, Inno La configuration actuelle rivalise et dépasse même la plupart des installateurs commerciaux en termes de fonctionnalités et de stabilité. ") (Je voudrais simplement que plus de personnes utilisent InnoSetup)
HTH
Ce script (http://www.autohotkey.com/board/topic/63210-modify-system-path-gui/
inclut tous les appels d’API Windows nécessaires pouvant être modifiés pour répondre à vos besoins. Il s'agit en réalité d'une interface graphique AutoHotkey permettant de modifier facilement le chemin système. Doit être exécuté en tant qu'administrateur.