簡體   English   中英

python:如何從 HKLM 中刪除注冊表項(和子項)(出現錯誤 5)

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

我正在嘗試通過 python 腳本刪除某些注冊表項。
我從“HKEY_CURRENT_USER”中讀取和刪除密鑰沒有問題,但是嘗試從“HKEY_LOCAL_MACHINE”中執行相同的操作,給我帶來了可怕的WindowsError: [Error 5] Access is denied
我正在通過 IDLE IDE 運行腳本,具有管理員權限。
這是代碼:

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

您需要先刪除所有子項,然后才能刪除密鑰。

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

這是你如何運行它:

deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node", "App")
deleteSubkey(_winreg.HKEY_CURRENT_USER, "software\\wow6432node\\App")

解開這個老問題,這里是 ChrisHiebert 遞歸函數的更新版本:

  • 處理 Python 3(使用 Python 3.7.1 測試)
  • 處理多個注冊表架構(例如,Wow64 for Python 32 on Windows 64)
  • 是否符合 PEP-8

以下示例顯示了使用體系結構鍵掩碼刪除所有注冊表體系結構(標准和重定向 WOW6432Node)中的兩個鍵的函數用法。 希望這會幫助某人:

    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)

只是我在這個話題上的兩分錢,但我遞歸到最低的子鍵並在解開時刪除:

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

其他帖子之間的區別在於,如果num >0,我不會嘗試刪除,因為它會隱式失敗(如文檔中所述)。 所以我不會浪費時間去嘗試是否有子鍵。

弄清楚了!
原來注冊表項不是空的並且包含多個子項。
我必須先枚舉並刪除子鍵,然后才能從 HKLM 中刪除主鍵。 (還添加了“try...except”,因此它不會破壞整個代碼,以防萬一出現問題)。

這是我的解決方案。 我喜歡使用with語句,以便不必手動關閉密鑰。 首先,我檢查子鍵並在刪除鍵本身之前刪除它們。 如果不存在子鍵, EnumKey會引發 OSError。 我用它來打破循環。

from winreg import *

def delete_key(key: Union[HKEYType, int], sub_key_name: str):
    with OpenKey(key, sub_key_name) as sub_key:
        while True:
            try:
                sub_sub_key_name = EnumKey(sub_key, 0)
                delete_key(sub_key, sub_sub_key_name)
            except OSError:
                break

    DeleteKey(key, sub_key_name)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM