[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