How To Add To And Remove From System's Environment Variable "path"?
Solution 1:
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 # synonymousimport os
import sys
try:
import winreg
unicode = strexcept ImportError:
import _winreg as winreg # Python 2.xclassEnvironment(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()
defget(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
defset(self, name, value):
if value:
winreg.SetValueEx(self.key, name, 0, winreg.REG_EXPAND_SZ, value)
else:
winreg.DeleteValue(self.key, name)
self.notify()
defnotify(self):
self.SendMessage(self.HWND_BROADCAST, self.WM_SETTINGCHANGE, 0, u'Environment')
Environment = Environment() # singletion - create instance
PATH_VAR = 'PATH'defappend_path_envvar(addpath):
defcanonical(path):
path = unicode(path.upper().rstrip(os.sep))
return winreg.ExpandEnvironmentStrings(path) # Requires Python 2.6+
canpath = canonical(addpath)
curpath = Environment.get(PATH_VAR, '')
ifnotany(canpath == subpath
for subpath in canonical(curpath).split(os.pathsep)):
Environment.set(PATH_VAR, os.pathsep.join((curpath, addpath)))
defremove_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 notin 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 pathsprint(Environment.get('path'))
Solution 2:
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(';') ifnotr'\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')
Solution 3:
There is a python package pathtub
(I am the author), which can do the job. You can read the code and docs on GitHub.
Installing
pip install pathtub
Example usage
Reading Path
from pathtub import get_path
# Getting path (can be 'process' (default), 'user' or 'machine')
user_path = get_path('user')
print(user_path)
# C:\Program Files\Java\jdk-13.0.1\bin;C:\Programs;C:\Programs\apache-maven-3.6.2\bin;C:\Programs\cloc;C:\Programs\fciv;C:\Python\Python37;C:\Python\Python37\lib\site-packages\pywin32_system32;C:\Python\Python37\Scripts;C:\texlive\2018\bin\win32;C:\Users\USER\AppData\Local\Microsoft\WindowsApps;C:\Users\USER\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\USER\AppData\Roaming\npm
Adding to path
from pathtub import add_to_path
added = add_to_path(r'C:\Add this folder\to user path', mode='user')
print(added)
#True# Adding duplicate entries is prevented
added = add_to_path(r'C:\Add this folder\to user path', mode='user')
print(added)
#False
Removing from Path
removed = remove_from_path(r'C:\Add this folder\to user path', mode='user')
print(removed)
#True# Removing non-existing folder just returns False
removed = remove_from_path(r'C:\Add this folder\to user path', mode='user')
print(removed)
#False
Requirements
Current implementation (v.1.1.2) uses Powershell for the permanent Path modifications. I have only tested this with newer (Python 3.7 and 3.8), but I guess it should work also on some older versions.
Solution 4:
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.
Solution 5:
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
Post a Comment for "How To Add To And Remove From System's Environment Variable "path"?"