[Tutor] walk registry using _winreg
Albert-Jan Roskam
fomcl at yahoo.com
Thu May 30 16:47:21 CEST 2013
______________________________
>From: Dave Angel <davea at davea.name>
>To: tutor at python.org
>Sent: Wednesday, May 29, 2013 2:11 PM
>Subject: Re: [Tutor] walk registry using _winreg
>
>
>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).
Hi Dave, sorry, Python 2.7 on Windows 7 Enterprise.
>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.
;-) I removed the "yield" statements at the last moment. I had indeed been looking at os.walk. I put them back now.
Also studied os.walk again.
>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.
Good catch! Thanks! I wrote a new version (sorry, I don't have access to pastebin in the office,
it's qualified as "online storage"). Here's the code. As far as I can tell, it does exactly what I want now.
I hope I used all your feedback. CAUTION to anyone who runs this code: it replaces a registry entry.
import _winreg
import os
def walkRegistry(regkey, keyToSet="file_locations", valueToSet="temp_dir",
HKEY=_winreg.HKEY_CURRENT_USER, verbose=False):
"""Recursively search the Windows registry, 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
i = 0
aReg = _winreg.OpenKey(HKEY, regkey)
try:
while True:
key = _winreg.EnumKey(aReg, i)
i += 1
if key:
new_regkey = os.path.join(regkey, key)
if key == keyToSet:
if verbose:
print "---> FOUND!!", new_regkey, key, keyToSet, valueToSet
with _winreg.OpenKey(HKEY, new_regkey) as anotherReg:
value_data = _winreg.QueryValueEx(anotherReg, valueToSet)[0]
yield new_regkey, valueToSet, value_data
for x in walkRegistry(new_regkey, keyToSet, valueToSet, HKEY, verbose):
yield x
except WindowsError:
pass
def setRegistry(regkey, value, data, HKEY=_winreg.HKEY_CURRENT_USER):
"""Set <value> (subkey) of <regkey> with <data>"""
hkey = [item for item in dir(_winreg) if getattr(_winreg, item) == HKEY][0]
print "setting value '%s' with data '%s' in regkey\n'%s\\%s'\n" % \
(value, data, hkey, regkey)
try:
aReg = _winreg.OpenKey(HKEY, regkey, 0, _winreg.KEY_ALL_ACCESS)
except:
aReg = _winreg.CreateKey(HKEY, regkey)
try:
_winreg.SetValueEx(aReg, value, 0, _winreg.REG_SZ, data)
finally:
_winreg.CloseKey(aReg)
if __name__ == "__main__":
regkey = u"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
args = regkey, u"Shell Folders", u"Cookies"
regdata = [(regkey, value, data) for regkey, value, data in walkRegistry(*args)]
if len(regdata) == 1:
regkey, value, existing_data = regdata[0]
new_data = os.getenv("temp")
setRegistry(regkey, value, new_data)
<snip>
More information about the Tutor
mailing list