[Tutor] walk registry using _winreg
eryksun
eryksun at gmail.com
Thu May 30 22:05:23 CEST 2013
On Thu, May 30, 2013 at 10:47 AM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> def walkRegistry(regkey, keyToSet="file_locations",
> valueToSet="temp_dir",
> HKEY=_winreg.HKEY_CURRENT_USER, verbose=False):
I suppose you don't need the "sam" option in your case, but in general
it's needed for 64-bit Windows in order to handle both native and
WOW64 keys.
For a WOW64 process, the native 64-bit keys can be read with
sam=KEY_READ | KEY_WOW64_64KEY. For a 64-bit process, the WOW64 keys
can be read with sam=KEY_READ | KEY_WOW64_32KEY.
A WOW64 process will have "PROCESSOR_ARCHITEW6432" defined in os.environ.
> aReg = _winreg.OpenKey(HKEY, regkey)
You should use a "with" statement here instead of depending on the
garbage collection of the generator frame.
> try:
> while True:
> key = _winreg.EnumKey(aReg, i)
> i += 1
> if key:
> new_regkey = os.path.join(regkey, key)
There's too much code here under the banner of one "try" suite.
OpenKey and QueryValueEx in the subsequent statements may raise a
WindowsError for various reasons.
Also, as you're currently doing things it leaves several open handles
as you recursively create generators. It's likely not an issue (the
registry isn't deeply nested), but in general I prefer to close a
resource as immediately as is possible.
I'd enumerate the subkeys in a list and only yield a key/value match
for the current regkey (that's basically how os.walk traverses the
file system). This can match on the initial key. If you don't want
that, it can be worked around (e.g. a flag, or a helper function), but
I don't think the additional complexity is worth it.
import os
import _winreg
def walkRegistry(regkey,
keyToSet="file_locations",
valueToSet="temp_dir",
HKEY=_winreg.HKEY_CURRENT_USER,
sam=_winreg.KEY_READ,
onerror=None,
verbose=False):
try:
aReg = _winreg.OpenKey(HKEY, regkey)
except WindowsError as e:
if onerror is not None:
onerror(e)
return
i = 0
subkeys = []
with aReg:
while True:
try:
subkeys.append(_winreg.EnumKey(aReg, i))
except WindowsError:
break
i += 1
# check the key name; not the key path
if os.path.basename(regkey) == keyToSet:
if verbose:
print "---> FOUND KEY:", regkey
try:
data = _winreg.QueryValueEx(aReg, valueToSet)[0]
except WindowsError: # value not found
pass
else:
if verbose:
print "---> FOUND KEY,VALUE PAIR"
yield regkey, valueToSet, data
for key in subkeys:
new_regkey = os.path.join(regkey, key)
for item in walkRegistry(
new_regkey, keyToSet, valueToSet,
HKEY, sam, onerror, verbose):
yield item
Minimally tested (sorry):
>>> HKEY = _winreg.HKEY_LOCAL_MACHINE
>>> regkey = r'Software\Python\PythonCore\2.7'
>>> res = list(
... walkRegistry(regkey, 'PythonPath', '', HKEY, verbose=True))
---> FOUND KEY: Software\Python\PythonCore\2.7\PythonPath
---> FOUND KEY,VALUE PAIR
>>> res[0][2]
u'C:\\Python27\\Lib;C:\\Python27\\DLLs;C:\\Python27\\Lib\\lib-tk'
More information about the Tutor
mailing list