This modules provides a few handy functions to retrieve the path names of some windows system directories from the registry [1] and the environment. These path names can be different depending on OS version, installation language, current user and personal setup. Because of this, they should not be included statically in your program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | # winpaths.py
"""Functions for getting system/language/user dependent paths on windows.
All path names returned by the functions of this module are unicode strings.
"""
__all__ = [
'HKCU', 'HKLM',
'SHELL_FOLDERS',
'USER_SHELL_FOLDERS',
'expandvars',
'get_appdata',
'get_common_shellfolders',
'get_homedir',
'get_sharedconf',
'get_shellfolders',
'get_userconf',
'get_windir'
]
__module__ = "winpaths"
__author__ = "Christopher Arndt"
__version__ = "0.1"
__revision__ = "$Rev$"
__date__ = "$Date$"
__copyright__ = "Python license"
# standard library modules
import _winreg, os
SHELL_FOLDERS = \
r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
USER_SHELL_FOLDERS = \
r'Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
HKCU = _winreg.HKEY_CURRENT_USER
HKLM = _winreg.HKEY_LOCAL_MACHINE
# helper functions
def _substenv(m):
return os.environ.get(m.group(1), m.group(0))
_env_rx = None
def expandvars(s):
"""Expand environment variables of form %var%.
Unknown variables are left unchanged.
"""
global _env_rx
if '%' not in s:
return s
if _env_rx is None:
import re
_env_rx = re.compile(r'%([^|<>=^%]+)%')
return _env_rx.sub(_substenv, s)
def _get_reg_value(key, subkey, name):
"""Return registry value specified by key, subkey, and name.
Environment variables in values of type REG_EXPAND_SZ are expanded
if possible.
"""
key = _winreg.OpenKey(key, subkey)
try:
ret = _winreg.QueryValueEx(key, name)
except WindowsError:
return None
else:
key.Close()
if ret[1] == _winreg.REG_EXPAND_SZ:
return expandvars(ret[0])
else:
return ret[0]
def _get_reg_user_value(key, name):
"""Return a windows registry value from the CURRENT_USER branch."""
return _get_reg_value(HKCU, key, name)
def _get_reg_machine_value(key, name):
"""Return a windows registry value from the LOCAL_MACHINE branch."""
return _get_reg_value(HKLM, key, name)
# public functions
def get_appdata():
"""Return path of directory where apps should store user specific data."""
return _get_reg_user_value(SHELL_FOLDERS, 'AppData')
def get_common_shellfolders():
"""Return mapping of shell folder names (all users) to paths."""
return get_shellfolders(branch=HKLM)
def get_homedir():
"""Return path to user home directory, i.e. 'My Files'."""
return _get_reg_user_value(SHELL_FOLDERS, 'Personal')
def get_sharedconf(prog, *args):
"""Return path to shared configuration data for 'prog' from 'vendor'.
Additional arguments are appended via os.path.join().
See also: get_user_conf()
"""
return os.path.join(
_get_reg_machine_value(SHELL_FOLDERS, 'Common AppData'),
vendor, prog, *args
)
def get_shellfolders(branch=HKCU, key=SHELL_FOLDERS):
"""Return mapping of shell folder names (current user) to paths."""
key = _winreg.OpenKey(branch, key)
folders = {}
i = 0
while True:
try:
ret = _winreg.EnumValue(key, i)
if ret[2] == _winreg.REG_EXPAND_SZ:
folders[ret[0]] = expandvars(ret[1])
else:
folders[ret[0]] = ret[1]
except WindowsError:
break
i +=1
key.Close()
return folders
def get_userconf(vendor, prog, *args):
"""Return path to user configuration data for 'prog' from 'vendor'.
Additional arguments are appended via os.path.join(), e.g.
use like this:
optionsfn = get_userconf("ACME Soft", "Exploder", "Options.xml")
"""
return os.path.join(get_appdata(), vendor, prog, *args)
def get_windir():
"""Convenience function to get path to windows installation directory."""
return unicode(os.environ["WINDIR"])
|
This module is especially useful, if your program wants to read/write configuration data from/to files (see recipe 146305 [2] for storing configuration data in the registry).
Example:
>>> from ConfigParser import RawConfigParser
>>> parser = RawConfigParser()
>>> parser.read(get_userconf("ACME Soft", "Exploder", "config.ini"))
Related recipes:
[1] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66011 [2] http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146305
win32api.ExpandEnvironmentStrings is our choice! 8-). Function expandvars are easily replaced by win32api.ExpandEnvironmentStrings
expandvars. Good to know! I am not very familiar with the win32 extensions.
But my module would work with just the Python standard library without win32api installed.