How to add to and remove from system's environment variable “PATH”?

随声附和 提交于 2019-12-21 01:08:14

问题


How do I permanently add the path to system's environment variable "PATH"?

I want to only add the path if it does not already exist.

Also I want to remove all paths that contain a folder name such as \myprogram whether it be:

C:\path\to\myprogram\dist; or D:\another\path\to\myprogram\dist;


回答1:


import _winreg as reg
import win32gui
import win32con


# read the value
key = reg.OpenKey(reg.HKEY_CURRENT_USER, 'Environment', 0, reg.KEY_ALL_ACCESS)
# use this if you need to modify the system variable and if you have admin privileges
#key = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 0, reg.KEY_ALL_ACCESS) 
try
    value, _ = reg.QueryValueEx(key, 'PATH')
except WindowsError:
    # in case the PATH variable is undefined
    value = ''

# modify it
value = ';'.join([s for s in value.split(';') if not r'\myprogram' in s])

# write it back
reg.SetValueEx(key, 'PATH', 0, reg.REG_EXPAND_SZ, value)
reg.CloseKey(key)

# notify the system about the changes
win32gui.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')



回答2:


Here's something that does what you want which is similar to code in the jaraco.windows project. And like it, only uses built-in Python modules—so doesn't require first downloading and installing the pywin32 extensions. Plus it's Python 2.6+ and 3.x compatible and supports Unicode environment variables and values (directory paths in this case).

Note that Windows administrator rights are required to change the permanent system-level environment variables.

import ctypes
from ctypes.wintypes import HWND, UINT, WPARAM, LPARAM, LPVOID
LRESULT = LPARAM  # synonymous
import os
import sys
try:
    import winreg
    unicode = str
except ImportError:
    import _winreg as winreg  # Python 2.x

class Environment(object):
    path = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
    hklm = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
    key = winreg.OpenKey(hklm, path, 0, winreg.KEY_READ | winreg.KEY_WRITE)
    SendMessage = ctypes.windll.user32.SendMessageW
    SendMessage.argtypes = HWND, UINT, WPARAM, LPVOID
    SendMessage.restype = LRESULT
    HWND_BROADCAST = 0xFFFF
    WM_SETTINGCHANGE = 0x1A
    NO_DEFAULT_PROVIDED = object()

    def get(self, name, default=NO_DEFAULT_PROVIDED):
        try:
            value = winreg.QueryValueEx(self.key, name)[0]
        except WindowsError:
            if default is self.NO_DEFAULT_PROVIDED:
                raise ValueError("No such registry key", name)
            value = default
        return value

    def set(self, name, value):
        if value:
            winreg.SetValueEx(self.key, name, 0, winreg.REG_EXPAND_SZ, value)
        else:
            winreg.DeleteValue(self.key, name)
        self.notify()

    def notify(self):
        self.SendMessage(self.HWND_BROADCAST, self.WM_SETTINGCHANGE, 0, u'Environment')

Environment = Environment()  # singletion - create instance

PATH_VAR = 'PATH'

def append_path_envvar(addpath):
    def canonical(path):
        path = unicode(path.upper().rstrip(os.sep))
        return winreg.ExpandEnvironmentStrings(path)  # Requires Python 2.6+
    canpath = canonical(addpath)
    curpath = Environment.get(PATH_VAR, '')
    if not any(canpath == subpath
                for subpath in canonical(curpath).split(os.pathsep)):
        Environment.set(PATH_VAR, os.pathsep.join((curpath, addpath)))

def remove_envvar_path(folder):
    """ Remove *all* paths in PATH_VAR that contain the folder path. """
    curpath = Environment.get(PATH_VAR, '')
    folder = folder.upper()
    keepers = [subpath for subpath in curpath.split(os.pathsep)
                if folder not in subpath.upper()]
    Environment.set(PATH_VAR, os.pathsep.join(keepers))

Sample usage:

print(Environment.get('path'))
append_path_envvar(r'C:\path\to\myprogram\dist')
append_path_envvar(r'D:\another\path\to\myprogram\dist')
print(Environment.get('path'))
remove_envvar_path(r'\myprogram')  # remove *both* added paths
print(Environment.get('path'))



回答3:


I am inferring from the paths in your question that your are interested in doing this on the Windows platform.

The documentation describes the process:

To programmatically add or modify system environment variables, add them to the HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment registry key, then broadcast a WM_SETTINGCHANGE message with lParam set to the string "Environment". This allows applications, such as the shell, to pick up your updates.




回答4:


You should check os.environ. It's a dictionary that can be manipulated directly or via os.putenv:

Set the environment variable named varname to the string value. Such changes to the environment affect subprocesses started with os.system(), popen() or fork() and execv().

Hence:

>>> import os
>>> os.environ["PATH"] =  path_old + ":/tmp/hallo" 
>>> os.environ["PATH"] 
'/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/vendor_perl:/usr/bin/core_perl:/tmp/hallo'

[update]

according to this answer you can make them persistent via windows registry



来源:https://stackoverflow.com/questions/21138014/how-to-add-to-and-remove-from-systems-environment-variable-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!