2014-01-15 109 views

回答

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

我从你的问题,你有兴趣做这个路径推断在Windows平台上。

documentation描述的过程:

以编程方式添加或修改系统环境变量,把它们添加到HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \控制\会话管理\环境的注册表项,然后广播用WM_SETTINGCHANGE消息lParam设置为字符串“Environment”。这使应用程序(如shell)能够获取更新。

+1

你知道任何Python库或简单脚本接受参数并为你做的工作? –

+0

win32xxx可以发送消息,而winreg则是注册表 –

-1

您应该检查os.environ。这是一个字典,可以直接或通过os.putenv

将名为varname的环境变量设置为字符串值。 对环境所做的更改会影响以 os.system(),popen()或fork()和execv()开头的子流程。

因此:

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

[更新]

根据to this answer你可以让他们通过Windows注册表持久

+0

您不能“神奇地”使用Windows注册表对“os.environ”进行持久更改。你必须在那里写一个具体的价值。你不需要修改'os.environ'来执行此操作。而且,你不需要读取它:'os.environ [“PATH”]的值由两个值组成:用户PATH和系统PATH,它们存储在不同的注册表项中。您应该读取相应的注册表值。 – utapyngo

5

这里的东西,你想要做什么是类似于jaraco.windows项目中的代码。就像它一样,只使用内置的Python模块 - 因此不需要先下载并安装pywin32扩展。 加上Python 2.6+和3.x兼容,并支持Unicode环境变量和值(在这种情况下为目录路径)。

请注意,需要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)) 

使用范例:

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

辉煌!它真的是以最好的方式回答这个问题。为我节省了2个小时。 –

+0

@瓦西里:不客气。注意如果您有兴趣,我只做了一些小改进。 – martineau