2011-03-08 153 views
18
from _winreg import * 

"""print r"*** Reading from SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***" """ 
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) 

aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") 
for i in range(1024): 
    try: 
     asubkey=EnumKey(aKey,i) 
     val=QueryValueEx(asubkey, "DisplayName") 
     print val 
    except EnvironmentError: 
     break 

任何人都可以請糾正錯誤......我只是想關鍵的HKLM \ SOFTWARE \微軟\的Windows \ CurrentVersion \卸載 的子項中顯示「顯示名稱」這是錯誤我得到..Python代碼讀取註冊表

Traceback (most recent call last): 
    File "C:/Python25/ReadRegistry", line 10, in <module> 
    val=QueryValueEx(asubkey, "DisplayName") 
TypeError: The object is not a PyHKEY object 
+1

順便說一句,當你看到這樣的錯誤,它的工作嘗試'print(type(asubkey).__ name __)'來了解你正在處理的內容。 – yurymik 2011-03-08 02:12:58

回答

24

DocumentationEnumKey返回字符串鍵的名稱。你必須用​​函數明確地打開它。我已修復您的代碼段:


from _winreg import * 

"""print r"*** Reading from SOFTWARE\Microsoft\Windows\CurrentVersion\Run ***" """ 
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) 

aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") 
for i in range(1024): 
    try: 
     asubkey_name=EnumKey(aKey,i) 
     asubkey=OpenKey(aKey,asubkey_name) 
     val=QueryValueEx(asubkey, "DisplayName") 
     print val 
    except EnvironmentError: 
     break 

請注意,並非每個鍵都具有「DisplayName」值。

+2

當您調用'OpenKey'時,如果您使用打開鍵作爲第一個參數,則不必爲鍵提供完整路徑。 – Velociraptors 2011-03-08 01:52:52

+1

是的,你說得對。固定。 – yurymik 2011-03-08 02:10:17

+2

它沒有輸出.. – 2011-03-08 06:24:17

5

由於它的_winreg.QueryValueEx文檔中說,你需要傳遞一個已經打開的關鍵。 EnumKey返回一個字符串,而不是一個打開的鍵。

aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) 
aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") 
for i in range(1024): 
    try: 
     keyname = EnumKey(aKey, i) 
     asubkey = OpenKey(aKey, keyname) 
     val = QueryValueEx(asubkey, "DisplayName") 
     print val 
    except WindowsError: 
     break 
13

x64上的x86怎麼樣? Use 64-bit Specific Types

如果「卸載」中有超過1024個子鍵會怎麼樣? Use _winreg.QueryInfoKey(key)

的Python 2:

import errno, os, _winreg 
proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() 
proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() 

if proc_arch == 'x86' and not proc_arch64: 
    arch_keys = {0} 
elif proc_arch == 'x86' or proc_arch == 'amd64': 
    arch_keys = {_winreg.KEY_WOW64_32KEY, _winreg.KEY_WOW64_64KEY} 
else: 
    raise Exception("Unhandled arch: %s" % proc_arch) 

for arch_key in arch_keys: 
    key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, _winreg.KEY_READ | arch_key) 
    for i in xrange(0, _winreg.QueryInfoKey(key)[0]): 
     skey_name = _winreg.EnumKey(key, i) 
     skey = _winreg.OpenKey(key, skey_name) 
     try: 
      print _winreg.QueryValueEx(skey, 'DisplayName')[0] 
     except OSError as e: 
      if e.errno == errno.ENOENT: 
       # DisplayName doesn't exist in this skey 
       pass 
     finally: 
      skey.Close() 

的Python 3:

import errno, os, winreg 
proc_arch = os.environ['PROCESSOR_ARCHITECTURE'].lower() 
proc_arch64 = os.environ['PROCESSOR_ARCHITEW6432'].lower() 

if proc_arch == 'x86' and not proc_arch64: 
    arch_keys = {0} 
elif proc_arch == 'x86' or proc_arch == 'amd64': 
    arch_keys = {winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY} 
else: 
    raise Exception("Unhandled arch: %s" % proc_arch) 

for arch_key in arch_keys: 
    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", 0, winreg.KEY_READ | arch_key) 
    for i in range(0, winreg.QueryInfoKey(key)[0]): 
     skey_name = winreg.EnumKey(key, i) 
     skey = winreg.OpenKey(key, skey_name) 
     try: 
      print(winreg.QueryValueEx(skey, 'DisplayName')[0]) 
     except OSError as e: 
      if e.errno == errno.ENOENT: 
       # DisplayName doesn't exist in this skey 
       pass 
     finally: 
      skey.Close() 
+1

錯過最後一項,xrange的停止參數是獨佔的。 – CrouZ 2015-07-22 10:37:57

+1

謝謝,放棄了'-1',因爲我認爲這就是你在說的。 – VertigoRay 2015-07-22 18:50:10

+2

請注意,即使操作系統是64位,%PROCESSOR_ARCHITECTURE%也會返回x86與32位Python。 – 2015-08-30 10:50:38

1

我簡化_winreg功能用於查詢一個給定的註冊表項的嵌套值。

舉例來說,這是多麼簡單直接查詢你問有關注冊表項:

key = r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall' 

for sub_key in get_sub_keys(key): 
    path = join(key, sub_key) 
    value = get_values(path, ['DisplayName', 'DisplayVersion', 'InstallDate']) 

    if value: 
     print value 

輸出

{'DisplayVersion': u'347.25', 'DisplayName': u'NVIDIA Control Panel 347.25', 'InstallDate': u'20150125'} 
{'DisplayVersion': u'347.25', 'DisplayName': u'NVIDIA Graphics Driver 347.25', 'InstallDate': u'20150125'} 
{'DisplayVersion': u'2.2.2', 'DisplayName': u'NVIDIA GeForce Experience 2.2.2', 'InstallDate': u'20150212'} 
... 

添加這些實用功能,以及:

from _winreg import * 
import os 

roots_hives = { 
    "HKEY_CLASSES_ROOT": HKEY_CLASSES_ROOT, 
    "HKEY_CURRENT_USER": HKEY_CURRENT_USER, 
    "HKEY_LOCAL_MACHINE": HKEY_LOCAL_MACHINE, 
    "HKEY_USERS": HKEY_USERS, 
    "HKEY_PERFORMANCE_DATA": HKEY_PERFORMANCE_DATA, 
    "HKEY_CURRENT_CONFIG": HKEY_CURRENT_CONFIG, 
    "HKEY_DYN_DATA": HKEY_DYN_DATA 
} 

def parse_key(key): 
    key = key.upper() 
    parts = key.split('\\') 
    root_hive_name = parts[0] 
    root_hive = roots_hives.get(root_hive_name) 
    partial_key = '\\'.join(parts[1:]) 

    if not root_hive: 
     raise Exception('root hive "{}" was not found'.format(root_hive_name)) 

    return partial_key, root_hive 


def get_sub_keys(key): 
    partial_key, root_hive = parse_key(key) 

    with ConnectRegistry(None, root_hive) as reg: 
     with OpenKey(reg, partial_key) as key_object: 
      sub_keys_count, values_count, last_modified = QueryInfoKey(key_object) 
      try: 
       for i in range(sub_keys_count): 
        sub_key_name = EnumKey(key_object, i) 
        yield sub_key_name 
      except WindowsError: 
       pass 


def get_values(key, fields): 
    partial_key, root_hive = parse_key(key) 

    with ConnectRegistry(None, root_hive) as reg: 
     with OpenKey(reg, partial_key) as key_object: 
      data = {} 
      for field in fields: 
       try: 
        value, type = QueryValueEx(key_object, field) 
        data[field] = value 
       except WindowsError: 
        pass 

      return data 


def get_value(key, field): 
    values = get_values(key, [field]) 
    return values.get(field) 


def join(path, *paths): 
    path = path.strip('/\\') 
    paths = map(lambda x: x.strip('/\\'), paths) 
    paths = list(paths) 
    result = os.path.join(path, *paths) 
    result = result.replace('/', '\\') 
    return result 
+0

謝謝,這個作品。但我將如何去提取特定子項的值?例如,如果我深入到「卸載」目錄中的特定程序(對於關鍵變量),則不會返回任何內容。 – Sensei 2017-01-02 21:03:12