简体   繁体   English

如何添加和删除系统的环境变量“PATH”?

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

How do I permanently add the path to system's environment variable "PATH"?如何将路径永久添加到系统的环境变量“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:另外我想删除所有包含文件夹名称的路径,例如\\myprogram是否是:

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

Here's something that does what you want which is similar to code in the jaraco.windows project.这里有一些可以做你想做的事情,类似于jaraco.windows项目中的代码。 And like it, only uses built-in Python modules —so doesn't require first downloading and installing the pywin32 extensions.和它一样,只使用内置的 Python 模块——所以不需要先下载和安装pywin32扩展。 Plus it's Python 2.6+ and 3.x compatible and supports Unicode environment variables and values (directory paths in this case).此外,它与 Python 2.6+ 和 3.x 兼容并支持 Unicode 环境变量和值(在这种情况下是目录路径)。

Note that Windows administrator rights are required to change the permanent system-level environment variables.请注意,更改永久系统级环境变量需要 Windows 管理员权限。

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

There is a python package pathtub (I am the author), which can do the job.有一个 python 包pathtub (我是作者),可以完成这项工作。 You can read the code and docs on GitHub .您可以在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.当前实现 (v.1.1.2) 使用 Powershell 进行永久路径修改。 I have only tested this with newer (Python 3.7 and 3.8), but I guess it should work also on some older versions.我只用较新的(Python 3.7 和 3.8)测试过这个,但我想它应该也适用于一些旧版本。

I am inferring from the paths in your question that your are interested in doing this on the Windows platform.我从您问题中的路径推断您有兴趣在 Windows 平台上执行此操作。

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".要以编程方式添加或修改系统环境变量,请将它们添加到 HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment 注册表项,然后广播一条 WM_SETTINGCHANGE 消息,其中 lParam 设置为字符串“Environment”。 This allows applications, such as the shell, to pick up your updates.这允许应用程序(例如 shell)获取您的更新。

You should check os.environ .你应该检查os.environ It's a dictionary that can be manipulated directly or via os.putenv :这是一个可以直接或通过os.putenv操作的字典:

Set the environment variable named varname to the string value.将名为 varname 的环境变量设置为字符串值。 Such changes to the environment affect subprocesses started with os.system(), popen() or fork() and execv().对环境的此类更改会影响以 os.system()、popen() 或 fork() 和 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根据此答案,您可以通过 Windows 注册表使它们持久化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM