I l@ve RuBoard Previous Section Next Section

7.8 Manipulating the Environment on Windows NT/2000/XP

Credit: Wolfgang Strobl

7.8.1 Problem

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.

7.8.2 Solution

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"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")
print "System Environment variables are:"
print "#", "name", "value", "type"
for i in range(1000):
        n, v, t = _winreg.EnumValue(y, i)
        print i, n, v, t
    except EnvironmentError:
        print "You have", i, "System Environment variables"

path = _winreg.QueryValueEx(y, "path")[0]
print "Your PATH was:", path

# Reopen Environment key for writing
y = _winreg.OpenKey(x,
    r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment",
    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:\\")

7.8.3 Discussion

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.

7.8.4 See Also

Documentation for the standard module _winreg in the Library Reference; Windows API documentation available from Microsoft (http://msdn.microsoft.com).

    I l@ve RuBoard Previous Section Next Section