import _winreg import itertools import struct from collections import namedtuple import windows from windows.generated_def.windef import KEY_READ, REG_QWORD class ExpectWindowsError(object): def __init__(self, errornumber): self.errornumber = errornumber def __enter__(self): pass def __exit__(self, etype, e, tb): return (etype == WindowsError and e.winerror == self.errornumber) KeyValue = namedtuple("KeyValue", ["name", "value", "type"]) """A registry value (name, value, type)""" class PyHKey(object): """A windows registry key""" def __init__(self, surkey, name, sam=KEY_READ): self.surkey = surkey self.name = name self.fullname = self.surkey.fullname + "\\" + self.name if self.name else self.surkey.name self.sam = sam self._phkey = None #self.phkey def __repr__(self): return ''.format(self.fullname) @property def phkey(self): if self._phkey is not None: return self._phkey try: self._phkey = _winreg.OpenKeyEx(self.surkey.phkey, self.name, 0, self.sam) except WindowsError as e: raise WindowsError(e.winerror, "Could not open registry key <{0}> ({1})".format(self.fullname, e.strerror)) return self._phkey @property def subkeys(self): """The subkeys of the registry key :type: [:class:`PyHKey`] - A list of keys""" res = [] with ExpectWindowsError(259): for i in itertools.count(): res.append(_winreg.EnumKey(self.phkey, i)) return [PyHKey(self, n) for n in res] @property def values(self): """The values of the registry key :type: [:class:`KeyValue`] - A list of values""" res = [] with ExpectWindowsError(259): for i in itertools.count(): name_value_type = _winreg.EnumValue(self.phkey, i) # _winreg doest not support REG_QWORD # See http://bugs.python.org/issue23026 if name_value_type[2] == REG_QWORD: name = name_value_type[0] value = struct.unpack("".format(value)) def set(self, name, value, type=None): """Set the value for ``name`` to ``value``. if ``type`` is None try to guess items""" if type is None: type = self._guess_value_type(value) if type == REG_QWORD: value = struct.pack("".format(name)) base_name, subkey = name.split("\\", 1) if base_name not in self.registry_base_keys: raise ValueError("Unknow registry base key <{0}>".format(base_name)) return self.registry_base_keys[base_name](subkey, sam)