Can python script constantly change windows environment variable? (elegantly)

Following my previous question, is it possible to create a Python script that constantly changes the Windows environment variable?

Changes to os.environ are not saved after python interpreter completes. If I had scripted this on UNIX, I could do something like:

set foo=`myscript.py` 

But alas, cmd.exe has nothing that works like the behavior of back back-tick. I saw a very protracted solution ... Of course, we can improve this:

 for /f "tokens=1* delims=" %%a in ('python ..\myscript.py') do set path=%path%;%%a 

Of course, minds at Microsoft have a better solution than that!

Note : an exact duplicate of this question .

+7
python windows scripting batch-file
source share
5 answers

Your long solution is probably the best idea; I do not think this is possible from Python directly. This article suggests another way to use a temporary batch file:

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

+1
source share

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

Using PyWin32 to access Windows COM objects, a Python program can use the WScript.Shell object environment property β€” a set of environment variables.

+5
source share

Windows sets environment variables from values ​​stored in the registry for each process independently.

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

+3
source share

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" 
+3
source share

This link provides a solution using the winreg built-in 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) 
+1
source share

All Articles