Думаю многие windows-программеры, работающие с реестром натыкались на жутко неудобный api. Во многих проектах имеются всяческие обертки над этими апи, чтобы хоть както упростить работу. Python не исключение, так как стандартная библиотека _winreg представляет из себя простую обертку над функциями winapi.
Данная библиотека значительно облегчает работу с реестром, скрывая все тонкости winapi под простым и понятным интерфейсом.
Клас предоставляет 3 способа для доступа к реестру.
Стиль мэппинга:
Winreg(HKEY_CURRENT_USER)['SOFTWARE']['RegTest']['TestInt'] = 10
Стиль классов:
Winreg(HKEY_CURRENT_USER).SOFTWARE.RegTest.TestInt = 10
Или простой строкой:
Winreg(HKEY_CURRENT_USER, 'SOFTWARE\\RegTest\\TestInt') = 10
Winreg(HKEY_CURRENT_USER)['SOFTWARE\\RegTest\\TestInt'] = 10
Чтобы перечислить все секции в ветке используем функцию keys, возврящающую итератор по подключам:
for i in keys(t.SOFTWARE.RegTest):
print repr(i)
Чтобы перечислить все значения в ветке используем функцию values, возврящающую итератор по парам (имя, значение):
for name,value in values(t.SOFTWARE.RegTest.test1):
print name, value
Вот и все, пользуйтесь на здоровье.
Вот еще несколько примернов работы:
from winreg import *
# set test ====================================
>>> t = Winreg(HKEY_CURRENT_USER)
>>> t.SOFTWARE.RegTest = {} #< creats empty section
>>> t.SOFTWARE.RegTest.TestString = u'TestString'
>>> t.SOFTWARE.RegTest.TestInt = 10
>>> t.SOFTWARE.RegTest.test1.value1 = u'val1'
>>> t.SOFTWARE.RegTest.test1.value2 = 1
>>> t.SOFTWARE.RegTest.test1.value3 = 2
>>> t.SOFTWARE.RegTest.test2 = {}
>>> t.SOFTWARE.RegTest.test3 = {}
>>> t.SOFTWARE.RegTest2.TestString = u'TestString'
>>> t.SOFTWARE.RegTest2.location = 1
# get test ====================================
# map-style
>>> int(t['SOFTWARE']['RegTest']['TestInt'])
10
# class-style
>>> str(t.SOFTWARE.RegTest.TestString)
'TestString'
# folder-style
>>> str(t['SOFTWARE\\RegTest\\TestString'])
'TestString'
# coerce test
>>> v = t.SOFTWARE.RegTest.TestInt
>>> 1+v, v+1, int(v)
(11, 11, 10)
# exceptions =============================
>>> try:
... print t.SOFTWARE.RegTest.test4
... except WindowsError, e:
... print e
[Error 2] Value not found: Winreg(winreg.HKEY_CURRENT_USER, r"SOFTWARE\\RegTest\\test4")
# iteration ==============================
# by keys
>>> for i in keys(t.SOFTWARE.RegTest):
... print repr(i)
Winreg(winreg.HKEY_CURRENT_USER, r"SOFTWARE\\RegTest\\test1")
Winreg(winreg.HKEY_CURRENT_USER, r"SOFTWARE\\RegTest\\test2")
Winreg(winreg.HKEY_CURRENT_USER, r"SOFTWARE\\RegTest\\test3")
# by values
>>> list(values(t.SOFTWARE.RegTest.test1))
[('value1', u'val1'), ('value2', 1), ('value3', 2)]
# deletion ==============================
>>> delete(t.SOFTWARE.RegTest.test1.value3)
>>> delete(t.SOFTWARE.RegTest.test3)
>>> delete(t.SOFTWARE.RegTest.test1)
>>> delete(t.SOFTWARE.RegTest.test2)
>>> delete(t.SOFTWARE.RegTest)
>>> delete(t.SOFTWARE.RegTest2)
winreg.py:
import _winreg, os
from _winreg import HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT,\
HKEY_CURRENT_CONFIG, HKEY_DYN_DATA, HKEY_PERFORMANCE_DATA, HKEY_USERS
hk2text = {
HKEY_LOCAL_MACHINE: 'HKEY_LOCAL_MACHINE',
HKEY_CURRENT_USER: 'HKEY_CURRENT_USER',
HKEY_CLASSES_ROOT: 'HKEY_CLASSES_ROOT',
HKEY_CURRENT_CONFIG: 'HKEY_CURRENT_CONFIG',
HKEY_DYN_DATA: 'HKEY_DYN_DATA',
HKEY_PERFORMANCE_DATA: 'HKEY_PERFORMANCE_DATA',
HKEY_USERS: 'HKEY_USERS',
}
class Winreg:
def __init__(self, root=None, location=''):
self.__dict__['location'] = location
self.__dict__['root'] = root
def __getattr__(self, location):
return Winreg(self.__dict__['root'], os.path.join(self.__dict__['location'], location))
def __getitem__(self, location):
return Winreg(self.__dict__['root'], os.path.join(self.__dict__['location'], location))
def __setattr__(self, location, value):
self.__setValue(location, value)
return value
def __setitem__(self, location, val):
self.__setValue(location, value)
return value
def __str__(self):
return unicode(self.__getValue())
def __setValue(self, location, value):
if isinstance(value, dict):
_winreg.CreateKey(self.__dict__['root'], os.path.join(self.__dict__['location'], location))
elif isinstance(value, unicode):
key = _winreg.CreateKey(self.__dict__['root'], self.__dict__['location'])
_winreg.SetValueEx(key, location, 0, _winreg.REG_SZ, value)
elif isinstance(value, int):
key = _winreg.CreateKey(self.__dict__['root'], self.__dict__['location'])
_winreg.SetValueEx(key, location, 0, _winreg.REG_DWORD, value)
else:
raise TypeError("valid types: dict, unicode, int")
def __getValue(self):
try:
a,b = os.path.split(self.__dict__['location'])
key = _winreg.OpenKey(self.__dict__['root'], a)
v = _winreg.QueryValueEx(key, b)
return v[0]
except WindowsError, e:
if e.winerror == 2:
raise WindowsError(e.winerror, 'Value not found: '+self.__repr__())
else:
raise WindowsError(e.winerror, self.__repr__())
def __int__(self):
return int(self.__getValue())
def __coerce__(self, other):
return self.__getValue(), other
def __repr__(self):
return 'Winreg(winreg.%s, r"%s")'%(hk2text[self.__dict__['root']], self.__dict__['location'])
def keys(reg):
key = _winreg.OpenKey(reg.__dict__['root'], reg.__dict__['location'])
class RegKeysIterator:
current = 0
def __iter__(self):
return self
def next(self):
try:
v = reg[_winreg.EnumKey(key, self.current)]
self.current += 1
except WindowsError, e:
if e.winerror == 259:
raise StopIteration
else:
raise
return v
return RegKeysIterator()
def values(reg):
key = _winreg.OpenKey(reg.__dict__['root'], reg.__dict__['location'])
class RegValuesIterator:
current = 0
def __iter__(self):
return self
def next(self):
try:
v = _winreg.EnumValue(key, self.current)[:2]
self.current += 1
return v
except WindowsError, e:
if e.winerror == 259:
raise StopIteration
else:
raise
return RegValuesIterator()
def delete(reg):
a,b = os.path.split(reg.__dict__['location'])
try:
key = _winreg.OpenKey(reg.__dict__['root'], a, 0, _winreg.KEY_WRITE)
try:
_winreg.DeleteValue(key, b)
except:
_winreg.DeleteKey(key, b)
except WindowsError, e:
raise WindowsError(e.winerror, 'Can not delete: ' + reg.__repr__())