2011-03-08 156 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