Scanning through Windows registry...
Hi everyone! Well, I have this need for a Python script that will scan through a selected hive (like HKEY_LOCAL_MACHINE) and replace all strings that contain word xxx (IE. foo) with yyy (IE. moo). I do not want partial results, but rather complete strings (no foome or the like, just foo). I have a basic understanding of Python, but this is beyond my skills. I was looking for something like this: open key (HKEY_LOCAL_MACHINE) while (not end of list) open next subkey search subkey for value (old) SetValue(key, subkey, REG_SZ, new) close subkey end while close key -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
Tim Golden wrote: > In a spirit of teaching people to fish... > > ... If you put something like "Python windows registry" into Google, you > get quite a few hits, the top one of which is probably pointing to the stdlib > _winreg module, but several others point towards wrapper classes, modules > etc. which provide a simpler or at least a different interface to the > registry. > > Have a look at those and see if you can't work out what to do. > > TJG The first link which points to the Python documentation for the _winreg module I already checked, even before coming here. I am wondering how I should do the loop I need (go through HKEY_LOCAL_MACHINE and read one subkey at a time, if it contains this 'foo' then change it into 'moo'). As I already said, I am by no means an expert in Python (heck, I learned the basics only a month ago). However, I am willing to learn. Also my prior experience with the Windows registry is mostly by the Registry Editor shipped with Windows. While I do understand what keys, values and hives are, I do not have a great experience in the others. If it's not too much to ask, maybe someone (who is much better than me) could make a code snippet that reads a certain hive and replaces values that are predetermined (preferably variables, not arguments if possible). If that's out of the question, at least push me gently into the right direction. So basically I am looking for these things: 1) Read one subkey from HKEY_LOCAL_MACHINE at a time (I think QueryValueEx() is needed here) 2) Check if said subkey contains some predetermined string (like 'foo' here) 3) If the above applies, change the value into another predetermined string (like 'moo' here) Also, how should I determine the length of the loop? I personally am too fond of the for loop, but if I need to use, like, while, then so be it. Thanks in advance. -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
Tim Golden wrote: > Well, I attach a kind of explanatory Noddy example I wrote a few years ago > for someone on the python-win32 list. I think, glancing over it, that it > includes > what you need to know, although not necessarily in the right order. I'm happy > to > explain if things aren't clear: > > > import _winreg > > HKLM = _winreg.HKEY_LOCAL_MACHINE > > # > # Set up a registry subtree under HKLM\Software > # which will look like this: > # > > # > # TimSoft > # | > # +-- App1 > # | > # +-- App2 > # | > # +-- App3 > # > > # > # The [TimSoft] key has a default (ie unnamed) value > # while the Appx keys each have two values: > # [Registered] - a string Y/N value > # [Version] - a DWORD value > # > > hSoftware = _winreg.OpenKey (HKLM, "Software") > hTimSoft = _winreg.CreateKey (hSoftware, "TimSoft") > > _winreg.SetValueEx (hTimSoft, None, 0, _winreg.REG_SZ, "All Tim's Software") > > hApp1 = _winreg.CreateKey (hTimSoft, "App1") > _winreg.SetValueEx (hApp1, "Version", 0, _winreg.REG_DWORD, 101) > _winreg.SetValueEx (hApp1, "Registered", 0, _winreg.REG_SZ, "Y") > > hApp2 = _winreg.CreateKey (hTimSoft, "App2") > _winreg.SetValueEx (hApp2, "Version", 0, _winreg.REG_DWORD, 202) > _winreg.SetValueEx (hApp2, "Registered", 0, _winreg.REG_SZ, "N") > > hApp3 = _winreg.CreateKey (hTimSoft, "App3") > _winreg.SetValueEx (hApp3, "Version", 0, _winreg.REG_DWORD, 303) > _winreg.SetValueEx (hApp3, "Registered", 0, _winreg.REG_SZ, "Y") > > # > # NB - no need to do an explicit "write": the Registry uses > # some sort of caching which eventually catches up with itself, > # so unless you plan to turn the machine off soon, don't > # bother with FlushKey or anything like that. > # > > # > # Now we start again, as though we were just querying > # > > hTimSoft = _winreg.OpenKey (HKLM, r"Software\TimSoft") > n_sub_keys, n_values, last_modified = _winreg.QueryInfoKey (hTimSoft) > print n_sub_keys, "sub keys", n_values, "values", last_modified, "nanoseconds > since 1600!" > > # > # Pick up the default value: really should try to > # interpret the default_type to determine if it's > # a number or a string or whatever, but... > # > default_value, default_type = _winreg.QueryValueEx (hTimSoft, None) > print "Default value:", default_value > > # > # Now, in this case I know (because I created them) that > # the TimSoft key has three subkeys, each of which has > # two values. But if I didn't... > # > print > for i in range (n_sub_keys): > subkey_name = _winreg.EnumKey (hTimSoft, i) > print subkey_name > > # > # Alternatively, if I hadn't done the QueryInfoKey above... > # > i = 0 > print > while 1: > try: > subkey_name = _winreg.EnumKey (hTimSoft, i) > except EnvironmentError: > break > else: > print subkey_name > i += 1 > > # > # Now, let's use the last key as an example > # and pick out its values. > # > print > print subkey_name > hAppKey = _winreg.OpenKey (hTimSoft, subkey_name) > i = 0 > while 1: > try: > name, value, type = _winreg.EnumValue (hAppKey, i) > print name, value, type > except EnvironmentError: > break > else: > print " %s => %s (type %s)" % (name, value, type) > i += 1 > > > > TJG Correct me if I'm wrong (which I just might be), but doesn't the above code go through the keys behind HKEY_LOCAL_MACHINE\Software\Timsoft\ ? Is it possible to use an empty value in: hTimSoft = _winreg.OpenKey (HKLM, r"Software\TimSoft") like: hTimSoft = _winreg.OpenKey (HKLM, "") so it would go all subkeys behind the "root" (in this case, HKEY_LOCAL_MACHINE)? The code is supposed to work even if I don't know all possible subkeys under HKEY_LOCAL_MACHINE. Creating dozens or hundreds of handles like the above is a bit... unappealing. Can I also use HKLM in the place of hTimSoft when I want to determine the amount of subkeys it has, like you did over here: n_sub_keys, n_values, last_modified = _winreg.QueryInfoKey (hTimSoft) Anyway, the above code seems interesting. I'll try a few tweaks here and there and see what happens. Thank you, Tim. -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
Thank you, I think I can manage now. It's nice that you could spare some time to help me in this, Tim. People like you make the world a better place :) I'll post my code here once I have time to write it, currently I'm rather busy. That is merely for optimization suggestions and for others who might need the same sort of code I did. Thank you once again. -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
On 7 touko, 14:25, Unknown Hero <[EMAIL PROTECTED]> wrote: > I'll post my code here once I have time to write it, currently I'm > rather busy. That is merely for optimization suggestions and for > others who might need the same sort of code I did. > > Thank you once again. Finally managed to get it to work (heh, I was pretty darn lost even though I had the best help) but as promised, I'll post my code here for those who might be interested in it. The biggest of thanks to Tim Golden, who basically walked me step-by-step through this. Most of the code is copied from his examples above. #Goes through all keys and subkeys in the selected hive (defined as root) and replaces the value 'old' with the value 'new' # #IMPORTANT! You should always back up the registry before attempting to modify it. #The author of this script CANNOT BE HELD RESPONSIVE for any damage caused by running this script. # #To customize the script to your liking, you can alter the values old, new, root. # #old and new can be any string value #root has to be one of the following: # # _winreg.HKEY_LOCAL_MACHINE # _winreg.HKEY_CURRENT_USER # _winreg.HKEY_CLASSES_ROOT # _winreg.HKEY_USERS # _winreg.HKEY_CURRENT_CONFIG import _winreg HIVES = { "HKEY_LOCAL_MACHINE" : _winreg.HKEY_LOCAL_MACHINE, "HKEY_CURRENT_USER" : _winreg.HKEY_CURRENT_USER, "HKEY_CLASSES_ROOT" : _winreg.HKEY_CLASSES_ROOT, "HKEY_USERS" : _winreg.HKEY_USERS, "HKEY_CURRENT_CONFIG" : _winreg.HKEY_CURRENT_CONFIG } old = "This was value before" new = "This is new value" start = "HKEY_LOCAL_MACHINE\\" startHandle = _winreg.HKEY_LOCAL_MACHINE #Values for start and startHandle are: HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT, HKEY_USERS, HKEY_CURRENT_CONFIG class RegKey: def __init__ (self, name, key): self.name = name self.key = key def __str__ (self): return self.name def walk (top): """walk the registry starting from the key represented by top in the form HIVE\\key\\subkey\\..\\subkey and generating key, subkey_names, values at each level. key is a lightly wrapped registry key, including the name and the HKEY object. subkey_names are simply names of the subkeys of that key values are 3-tuples containing (name, data, data-type). See the documentation for _winreg.EnumValue for more details. """ try: if "\\" not in top: top += "\\" root, subkey = top.split ("\\", 1) #print "KEY:", root + "\\" + subkey key = _winreg.OpenKey (HIVES[root], subkey, 0, _winreg.KEY_READ | _winreg.KEY_SET_VALUE) subkeys = [] i = 0 while True: try: subkeys.append (_winreg.EnumKey (key, i)) i += 1 except EnvironmentError: break values = [] i = 0 while True: try: values.append (_winreg.EnumValue (key, i)) i += 1 except EnvironmentError: break yield RegKey (top, key), subkeys, values for subkey in subkeys: for result in walk (top + "\\" + subkey): yield result except WindowsError: #print 'Could not open key', root + "\\" + subkey + "\n" pass basickeys = [] i = 0 while True: try: basickeys.append (_winreg.EnumKey (startHandle, i)) i += 1 except EnvironmentError: print i, 'subkeys found!' break for x in range(len(basickeys)): for key, subkey_names, values in walk (start + basickeys[x]): #print key for (name, data, type) in values: # print " ", name, "=>", data if type == _winreg.REG_SZ and old in data: _winreg.SetValueEx (key.key, name, 0, type, data.replace (old, new)) Not the most effecient code, I'm sure, but it does what I want it to do :D Thank you once more, Tim. Also, thank you, Mike, for your advice on saving the registry. I would have forgotten to note backing up the registry in the beginning if it wasn't for you bringing that up. :D -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
On 9 touko, 12:51, Unknown Hero <[EMAIL PROTECTED]> wrote: > Finally managed to get it to work (heh, I was pretty darn lost even > though I had the best help) but as promised, I'll post my code here > for those who might be interested in it. The biggest of thanks to Tim > Golden, who basically walked me step-by-step through this. Most of the > code is copied from his examples above. > > [large piece of code here] > > Not the most effecient code, I'm sure, but it does what I want it to > do :D > > Thank you once more, Tim. Also, thank you, Mike, for your advice on > saving the registry. I would have forgotten to note backing up the > registry in the beginning if it wasn't for you bringing that up. :D Hmm... Improving your code is always fun :D but quick fixes to make it replace search results that contain something more than 'old' here don't seem to work. So I made it command-line, with arguments Hive, old, new. If I ran the script as registry.py HKEY_LOCAL_MACHINE something "something else" and I had made dummy values to the registry like "there is something here" it won't update to "there is something else here". I tried this, can Tim (or someone else) possibly help? if type == _winreg.REG_SZ: Character = 0 Correct = 0 FoundStart = FoundEnd = 0 Found = False for y in range(len(data)): if Character < len(old): if old[Character] is data[y]: Character = Character + 1 Correct = Correct + 1 if Correct is len(old): Found = True Replace = "" Character = 0 for y in range(len(data)): if old[0] is data[y]: FoundStart = int(y) FoundEnd = FoundStart + oldLength for y in range(FoundStart): Replace = Replace + data[y] for y in range(len(new)): Replace = Replace + new[y] for y in range(FoundEnd, len(data)): Replace = Replace + data[y] if Found: _winreg.SetValueEx (key.key, name, 0, type, data.replace (old, Replace)) Thanks in advance. -- http://mail.python.org/mailman/listinfo/python-list
Re: Scanning through Windows registry...
Ah, never mind, got it to work. Here's the code now. I hope I won't run into another problems later :D #Goes through all keys and subkeys in the selected hive (defined as root) and replaces the value 'old' with the value 'new' # #IMPORTANT! You should always back up the registry before attempting to modify it. #The author of this script CANNOT BE HELD RESPONSIVE for any damage caused by running this script. # #To customize the script to your liking, you can alter the values old, new, root. # #old and new can be any string value #root has to be one of the following: # # _winreg.HKEY_LOCAL_MACHINE # _winreg.HKEY_CURRENT_USER # _winreg.HKEY_CLASSES_ROOT # _winreg.HKEY_USERS # _winreg.HKEY_CURRENT_CONFIG import _winreg #For accessing windows registry, included in Python 2.0. import sys #For reading arguments (command line), included in every Python release. HIVES = { "HKEY_LOCAL_MACHINE" : _winreg.HKEY_LOCAL_MACHINE, "HKEY_CURRENT_USER" : _winreg.HKEY_CURRENT_USER, "HKEY_CLASSES_ROOT" : _winreg.HKEY_CLASSES_ROOT, "HKEY_USERS" : _winreg.HKEY_USERS, "HKEY_CURRENT_CONFIG" : _winreg.HKEY_CURRENT_CONFIG } class RegKey: def __init__ (self, name, key): self.name = name self.key = key def __str__ (self): return self.name def walk (top): """walk the registry starting from the key represented by top in the form HIVE\\key\\subkey\\..\\subkey and generating key, subkey_names, values at each level. key is a lightly wrapped registry key, including the name and the HKEY object. subkey_names are simply names of the subkeys of that key values are 3-tuples containing (name, data, data-type). See the documentation for _winreg.EnumValue for more details. """ try: if "\\" not in top: top += "\\" root, subkey = top.split ("\\", 1) #print "KEY:", root + "\\" + subkey key = _winreg.OpenKey (HIVES[root], subkey, 0, _winreg.KEY_READ | _winreg.KEY_SET_VALUE) subkeys = [] i = 0 while True: try: subkeys.append (_winreg.EnumKey (key, i)) i += 1 except EnvironmentError: break values = [] i = 0 while True: try: values.append (_winreg.EnumValue (key, i)) i += 1 except EnvironmentError: break yield RegKey (top, key), subkeys, values for subkey in subkeys: for result in walk (top + "\\" + subkey): yield result except WindowsError: #print 'Could not open key', root + "\\" + subkey + ", access denied!\n" pass except: print 'Other error!' def main(start, startHandle, old, new): basickeys = [] i = 0 while True: try: basickeys.append (_winreg.EnumKey (startHandle, i)) i += 1 except EnvironmentError: # print i, 'subkeys found!' break for x in range(len(basickeys)): for key, subkey_names, values in walk (start + "\\" + basickeys[x]): # print key for (name, data, type) in values: #print " ", name, "=>", data if type == _winreg.REG_SZ: Character = 0 Correct = 0 FoundStart = FoundEnd = 0 Found = False for y in range(len(data)): try: if Character < len(old): # print old[Character], data[y] if old[Character] in data[y]: Character = Character + 1 Correct = Correct + 1 except: pass if Correct is len(old): #print 'Debug!' Replace = "" Character = 0 for y in range(len(data)): if not Found: if old[0] in data[y]: FoundStart = int(y) FoundEnd = FoundStart + len(old) Found = True #for y in range(FoundStart): # Replace = Replace + data[y] for y in range(len(new)): Replace = Replace + new[y] #for y in range(FoundEnd, len(data)): # Replace = Replace + data[y] Found = True if Found: #print "OLD:", old, "will be replaced with:", Replace _winreg.SetValueEx (key.key, name, 0, type, data.replace (old, Replace)) def help(): #Show help print 'USAGE: Registry.py [HIVE] [OLD] [NEW]' print ' HIVE: The root key in registry you want to go through.' print 'HKEY_CLASSES_ROOT' print 'HKEY_CURRENT_USER' print 'HKEY_LOCAL_MACHINE' print 'HKEY_USERS' print 'HKEY_CURRENT_CONFIG' print '' print ' OLD: The value to search for.' print 'Wrap multiword strings with \"\".' print '' print ' NEW: The value which will replace OLD.' print 'Wrap multiword strings with \"\".' #Check for arguments #HIVE, old, new while True: #Check if invalid number of arguments are given if len(sys.argv) is 1: help() break # for x in range(len(sys.argv)): #print 'sys.argv[' + str(x) + ']:', sys.argv[x] #Check if hive is