Credit: Wolfgang Strobl
You need to check and/or set
system-environment variables on Windows NT (or 2000 or XP) via the
registry, not in the transient way supported by
os.environ
.
Many Windows system-administration
tasks boil down to working with the Windows registry, so the
_winreg
module, part of the Python core, often
plays a crucial role in such scripts. This recipe reads all the
system-environment variables, then modifies one of them, accessing
the registry for both tasks:
import _winreg
x = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
y = _winreg.OpenKey(x,
r"SYSTEMCurrentControlSetControlSession ManagerEnvironment")
print "System Environment variables are:"
print "#", "name", "value", "type"
for i in range(1000):
try:
n, v, t = _winreg.EnumValue(y, i)
print i, n, v, t
except EnvironmentError:
print "You have", i, "System Environment variables"
break
path = _winreg.QueryValueEx(y, "path")[0]
print "Your PATH was:", path
_winreg.CloseKey(y)
# Reopen Environment key for writing
y = _winreg.OpenKey(x,
r"SYSTEMCurrentControlSetControlSession ManagerEnvironment",
0, _winreg.KEY_ALL_ACCESS)
# Now append C: to the path as an example of environment change
_winreg.SetValueEx(y, "path", 0, _winreg.REG_EXPAND_SZ, path+";C:\")
_winreg.CloseKey(y)
_winreg.CloseKey(x)
Python’s normal access to the environment, via
os.environ
, is transient: it deals with only the
environment of this process, and any change affects only processes
spawned by the original process after the change. This is true on all
platforms.
In system administration, program installation, and other such uses, you may prefer to check and change the system-level environment variables, which are automatically set for each process started normally at process startup time. On Unix-like platforms, and on Windows 95/98/ME, such system-level environment variables are set by startup scripts, so your task is to parse and/or change those scripts in appropriate ways.
On Windows NT/2000/XP, however, system-level environment variables
are stored in the system registry, which makes this task
substantially easier. The Python standard library, in the Python
distribution for Windows, comes with a
_winreg
module that lets scripts read and write
the registry on any kind of Windows machine. This recipe shows how to
use _winreg
to read the system-environment
variables and, as a further example, how to modify the
PATH
environment variable.
The
ConnectRegistry
function of the _winreg
module returns a registry
object. The module’s other functions take that
object, or another registry key object, as their first argument. When
you are done with a key or a whole registry, you pass it to the
CloseKey
function.
The
OpenKey
function returns a registry key object: its first argument is a
registry object, and the second is a path in it. The path needs
backslashes, so we use the
Python raw-string syntax
(r'...'
) to avoid having to double up each
backslash. The
EnumValue
function takes a key and an index and returns a triple of name,
value, and type for that entry in the key, or raises
EnvironmentError
if there aren’t
that many entries in the key. In this recipe, we call it with
progressively larger indices, from 0 and up, and catch the exception
to learn the exact number of entries in the environment key.
QueryValueEx
takes the key and an entry name and returns the value for that entry.
SetValueEx
also takes flags (normally 0), a type code (many constants for which
are found in _winreg
), and finally a value, and
sets the given value and type for the entry of that name.
The script in this recipe can be run only by a user with suitable administrative privileges, of course, as it changes a protected part of the registry. This doesn’t matter under versions of Windows that don’t enforce protection, such as Windows 95, but it does for versions that do enforce protection, such as Windows 2000.
Documentation for the standard module _winreg
in
the Library Reference; Windows API documentation
available from Microsoft (http://msdn.microsoft.com).