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

别说谁变了你拦得住时间么 提交于 2020-06-27 16:15:32

问题


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')

回答1:


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")



回答2:


Figured it out!
turns out the registry key wasn't empty and contained multiple subkeys.
i had to enumerate and delete the subkeys first, and only then i was able to delete the main key from HKLM. (also added "try...except", so it wouldn't break the whole code, it case there were problems).




回答3:


Unburying this old question, here's an updated version of ChrisHiebert's recursive function that:

  • Handles Python 3 (tested with Python 3.7.1)
  • Handles multiple registry architectures (eg Wow64 for Python 32 on Windows 64)
  • Is PEP-8 compliant

The following example shows function usage to delete two keys in all registry architectures (standard and redirected WOW6432Node) by using architecture key masks. Hopefully this will help someone:

    import winreg


    def delete_sub_key(key0, current_key, arch_key=0):

        open_key = winreg.OpenKey(key0, current_key, 0, winreg.KEY_ALL_ACCESS | arch_key)
        info_key = winreg.QueryInfoKey(open_key)
        for x in range(0, info_key[0]):
            # NOTE:: This code is to delete the key and all sub_keys.
            # If you just want to walk through them, then
            # you should pass x to EnumKey. sub_key = winreg.EnumKey(open_key, x)
            # Deleting the sub_key will change the sub_key count used by EnumKey.
            # We must always pass 0 to EnumKey so we
            # always get back the new first sub_key.
            sub_key = winreg.EnumKey(open_key, 0)
            try:
                winreg.DeleteKey(open_key, sub_key)
                print("Removed %s\\%s " % (current_key, sub_key))
            except OSError:
                delete_sub_key(key0, "\\".join([current_key,sub_key]), arch_key)
                # No extra delete here since each call
                # to delete_sub_key will try to delete itself when its empty.

        winreg.DeleteKey(open_key, "")
        open_key.Close()
        print("Removed %s" % current_key)
        return


    # Allows to specify if operating in redirected 32 bit mode or 64 bit, set arch_keys to 0 to disable
    arch_keys = [winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY]

    # Base key
    root = winreg.HKEY_LOCAL_MACHINE

    # List of keys to delete
    keys = ['SOFTWARE\MyInstalledApp', 'SOFTWARE\SomeKey\SomeOtherKey']

    for key in keys:
        for arch_key in arch_keys:
            try:
                delete_sub_key(root, key, arch_key)
            except OSError as e:
                print(e)


来源:https://stackoverflow.com/questions/38205784/python-how-to-delete-registry-key-and-subkeys-from-hklm-getting-error-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!