Can a python script persistently change a Windows environment variable? (elegantly)

后端 未结 5 1950
失恋的感觉
失恋的感觉 2020-12-16 02:34

Following on from my previous question, is it possible to make a Python script which persistently changes a Windows environment variable?

Changes to os.environ do n

相关标签:
5条回答
  • 2020-12-16 02:42

    Your long-winded solution is probably the best idea; I don't believe this is possible from Python directly. This article suggests another way, using a temporary batch file:

    http://code.activestate.com/recipes/159462/

    0 讨论(0)
  • 2020-12-16 02:46

    This link provides a solution that uses the built-in winreg library.

    (copypasta)

    import sys
    from subprocess import check_call
    if sys.hexversion > 0x03000000:
        import winreg
    else:
        import _winreg as winreg
    
    class Win32Environment:
        """Utility class to get/set windows environment variable"""
    
        def __init__(self, scope):
            assert scope in ('user', 'system')
            self.scope = scope
            if scope == 'user':
                self.root = winreg.HKEY_CURRENT_USER
                self.subkey = 'Environment'
            else:
                self.root = winreg.HKEY_LOCAL_MACHINE
                self.subkey = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
    
        def getenv(self, name):
            key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_READ)
            try:
                value, _ = winreg.QueryValueEx(key, name)
            except WindowsError:
                value = ''
            return value
    
        def setenv(self, name, value):
            # Note: for 'system' scope, you must run this as Administrator
            key = winreg.OpenKey(self.root, self.subkey, 0, winreg.KEY_ALL_ACCESS)
            winreg.SetValueEx(key, name, 0, winreg.REG_EXPAND_SZ, value)
            winreg.CloseKey(key)
            # For some strange reason, calling SendMessage from the current process
            # doesn't propagate environment changes at all.
            # TODO: handle CalledProcessError (for assert)
            check_call('''\
    "%s" -c "import win32api, win32con; assert win32api.SendMessage(win32con.HWND_BROADCAST, win32con.WM_SETTINGCHANGE, 0, 'Environment')"''' % sys.executable)
    
    0 讨论(0)
  • 2020-12-16 02:51

    You might want to try Python Win32 Extensions, developed by Mark Hammond, which is included in the ActivePython (or can be installed separately). You can learn how to perform many Windows related tasks in Hammond's and Robinson's book.

    Using PyWin32 to access windows COM objects, a Python program can use the Environment Property of the WScript.Shell object - a collection of environment variables.

    0 讨论(0)
  • 2020-12-16 02:51

    Windows sets Environment variables from values stored in the Registry for each process independently.

    However, there is a tool in the Windows XP Service Pack 2 Support Tools named setx.exe that allows you to change global Environment variables from the command line.

    0 讨论(0)
  • 2020-12-16 03:03

    My solution using win32api:

    import os, sys, win32api, win32con
    '''Usage: appendenv.py envvar data_to_append'''
    def getenv_system(varname, default=None):
        '''
        Author: Denis Barmenkov <barmenkov at bpc.ru>
    
        Copyright: this code is free, but if you want to use it, 
                   please keep this multiline comment along with function source. 
                   Thank you.
    
        2006-01-28 15:30
        '''
        v = default
        try:
            rkey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
            try:
                v = str(win32api.RegQueryValueEx(rkey, varname)[0])
                v = win32api.ExpandEnvironmentStrings(v)
            except:
                pass
        finally:
            win32api.RegCloseKey(rkey)
        return v
    
    #My set function
    def setenv_system(varname, value):
        try:
            rkey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment',0 ,win32con.KEY_WRITE)
            try:
                win32api.RegSetValueEx(rkey, varname, 0, win32con.REG_SZ, value)
                return True
            except Exception, (error):
                pass
        finally:
            win32api.RegCloseKey(rkey)
        return False
    
    if len(sys.argv) == 3:
        value = getenv_system(sys.argv[1])
        if value:
            setenv_system(sys.argv[1],value + ";" + sys.argv[2])
            print "OK! %s = %s" % (sys.argv[1], getenv_system(sys.argv[1]))
        else:
            print "ERROR: No such environment variable. (%s)" % sys.argv[1]
    else:
        print "Usage: appendenv.py envvar data_to_append"
    
    0 讨论(0)
提交回复
热议问题