On 05/29/2013 04:11 AM, Albert-Jan Roskam wrote:
Hello,
I created a program to go through the windows registry and look for a certain key
("file_locations", though in the example I am using a key that every windows user has on
his/her computer). If found, I want to replace the data associated with value "temp_dir"
in that key. I have chosen this strategy because the exact registry keys may have changed from
version to version. Also, multiple versions of the program may be installed on a given computer. I
pasted the code below this mail, but also here: http://pastebin.com/TEkyekfi
Is this the correct way to do this? I would actually prefer to specify only "valueNameToSearch"
and not also "keyToSearch". As in: start walking through the registry starting at
<regkey>, return every key where a temp_dir is defined.
Thank you in advance!
Regards,
Albert-Jan
Please specify Python version. I'll assume 2.7. Obviously this is
Windows, though it's also conceivable that it matters which version of
Windows (XP, Win8, whatever).
First comment is that I'd be writing walkRegistry as a generator, using
yield for the items found, rather than building a list. It's generally
easier to reuse that way, and won't get you in trouble if there are tons
of matches. See os.walk for an example.
A generator also would naturally eliminate the need to know KeyToSearch.
import _winreg
import os
global __debug__
__debug__ = True
def walkRegistry(regkey, keyToSearch="file_locations",
valueNameToSearch="temp_dir", verbose=False):
"""Recursively search the Windows registry (HKEY_CURRENT_USER),
starting at top <regkey>. Return a list of three tuples that contain
the registry key, the value and the associated data"""
if verbose:
print regkey
aReg = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, regkey)
i, keys, founds = 0, [], []
try:
while True:
i += 1
key = _winreg.EnumKey(aReg, i)
I believe these are zero-based indexes, so you're skipping the first one.
keys.append(key)
if key == keyToSearch:
If this were a generator, you'd not be restricting the key here. By
restricting this key, you're limiting which subkeys you're going to
search, and in the general case, I believe you're currently skipping
values incorrectly.
keyx = os.path.join(regkey, key)
aReg = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, keyx)
Unsure here, but having another open here feels wrong.
data, type_ = _winreg.QueryValueEx(aReg, valueNameToSearch)
founds.append((keyx, valueNameToSearch, data))
Generally, recursion should happen here, rather than building a list and
doing the recursion below.
except WindowsError:
for key in keys:
try:
new_regkey = os.path.join(regkey, key)
walkRegistry(new_regkey, keyToSearch,
valueNameToSearch, verbose)
Nesting exceptions makes me nervous, and doing it recursively, makes me
even more so. If you move the recursion to the above area, then all the
exception has to do is break out of the while loop.
except WindowsError:
pass
return founds
def setRegistry(regkey, keyToSet, valueToSet, replacementData, verbose=False):
"""Search for <keyToSet> starting at top <regkey>. If <keyToSet> is found
exactly once, replace registry data associated with <valueToSet> with
<replacementData>."""
founds = walkRegistry(regkey, keyToSet, valueToSet, verbose)
If you changed walkRegistry as I suggest above, then this call becomes
something like:
for item in walkRegistry(regkey, keyToSet, valueToSet, verbose):
and inside the loop, you'll be testing the 'item' tuple for your
criteria. The test is done here, and NOT in the walkRegistry() function.
if not founds:
return
elif len(founds) == 1:
keyx, valueNameToSearch, data = founds[0]
else:
msg = "Registry value %r is found multiple times"
raise ValueError(msg % valueToSet)
if not __debug__:
try:
key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, keyx,
0, _winreg.KEY_ALL_ACCESS)
except:
key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, regkey)
_winreg.SetValueEx(keyx, valueToSet, 0, _winreg.REG_SZ,
replacementData)
_winreg.CloseKey(keyx)
regkey = u"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
print founds = walkRegistry(regkey, u"Shell Folders", u"Cookies", True)
setRegistry(regkey, u"Shell Folders", u"Cookies", "this is the replacement
value", False)
--
DaveA
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor