Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: how to delete registry key (and subkeys) from HKLM (getting error 5)

I'm trying to delete certain registry keys, via python script.
i have no problems reading and deleting keys from the "HKEY_CURRENT_USER", but trying to do the same from the "HKEY_LOCAL_MACHINE", gives me the dreaded WindowsError: [Error 5] Access is denied.
i'm running the script via the IDLE IDE, with admin privileges.
here's the code:

from _winreg import *    
ConnectRegistry(None,HKEY_LOCAL_MACHINE)
OpenKey(HKEY_LOCAL_MACHINE,r'software\wow6432node\App',0,KEY_ALL_ACCESS)
DeleteKey(OpenKey(HKEY_LOCAL_MACHINE,r'software\wow6432node'),'App')
like image 421
Tom Kidron Avatar asked Mar 12 '23 19:03

Tom Kidron


2 Answers

You need to remove all subkeys before you can delete the key.

def deleteSubkey(key0, key1, key2=""):
    import _winreg
    if key2=="":
        currentkey = key1
    else:
        currentkey = key1+ "\\" +key2

    open_key = _winreg.OpenKey(key0, currentkey ,0,_winreg.KEY_ALL_ACCESS)
    infokey = _winreg.QueryInfoKey(open_key)
    for x in range(0, infokey[0]):
        #NOTE:: This code is to delete the key and all subkeys.
        #  If you just want to walk through them, then 
        #  you should pass x to EnumKey. subkey = _winreg.EnumKey(open_key, x)
        #  Deleting the subkey will change the SubKey count used by EnumKey. 
        #  We must always pass 0 to EnumKey so we 
        #  always get back the new first SubKey.
        subkey = _winreg.EnumKey(open_key, 0)
        try:
            _winreg.DeleteKey(open_key, subkey)
            print "Removed %s\\%s " % ( currentkey, subkey)
        except:
            deleteSubkey( key0, currentkey, subkey )
            # no extra delete here since each call 
            #to deleteSubkey will try to delete itself when its empty.

    _winreg.DeleteKey(open_key,"")
    open_key.Close()
    print "Removed %s" % (currentkey)
    return

Here is an how you run it:

deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node", "App")
deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node\\App")
like image 152
ChrisHiebert Avatar answered Mar 18 '23 10:03

ChrisHiebert


Just my two cents on the topic, but I recurse to the lowest subkey and delete on unravel:

def delete_sub_key(root, sub):
    
    try:
        open_key = winreg.OpenKey(root, sub, 0, winreg.KEY_ALL_ACCESS)
        num, _, _ = winreg.QueryInfoKey(open_key)
        for i in range(num):
            child = winreg.EnumKey(open_key, 0)
            delete_sub_key(open_key, child)
        try:
           winreg.DeleteKey(open_key, '')
        except Exception:
           # log deletion failure
        finally:
           winreg.CloseKey(open_key)
    except Exception:
        # log opening/closure failure

The difference between the other posts is that I do not try to delete if num is >0 because it will fail implicitly (as stated in the docs). So I don't waste time to try if there are subkeys.

like image 27
pstatix Avatar answered Mar 18 '23 09:03

pstatix