可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
Could anyone please correct the error...i just want to display the "DisplayName" within the subkeys of the key the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall This is the error i get..
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:
Documentation says that EnumKey
returns string with key's name. You have to explicitly open it with _winreg.OpenKey
function. I've fixed your code snippet:
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
Please note, that not every key has "DisplayName" value available.
回答2:
What about x86 on x64? Use 64-bit Specific Types
What if there's more than 1024 sub-keys in "Uninstall"? 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()
回答3:
As it says in the _winreg.QueryValueEx documentation, you need to pass an already open key. EnumKey returns a string, not an open key.
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
回答4:
I simplified _winreg
functionality for querying a given registry key's nested values.
For instance, this is how straight-forward it is to query the registry key you asked about:
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
output
{'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'} ...
Add these utility functions as well:
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