web-dev-qa-db-fra.com

Comment mettre à jour la variable PATH de façon permanente à partir de cmd? les fenêtres

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 ).

116
vale4674

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.

42
David Heffernan

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.

144
panny

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 )

36
KilgoreCod

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/

8
ankostis

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:

  1. Interrogez les variables d’environnement utilisateur: reg query "HKEY_CURRENT_USER\Environment". Utilisez "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" pour LOCAL_MACHINE.
  2. Ajouter une nouvelle variable d’environnement utilisateur: 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 %%.
  3. Supprimer la variable env existante: reg delete "HKEY_CURRENT_USER\Environment" /v shared_dir.
4
razvanone

À 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

4
Steve F

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.

3
Evgeni Sergeev