Код Python для чтения реестра
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
Может кто-нибудь исправить ошибку... я просто хочу отобразить "DisplayName" в подразделах ключа HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
Это ошибка, которую я получаю.
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
В документации говорится, что EnumKey
возвращает строку с именем ключа. Вы должны явно открыть его с помощью функции _winreg.OpenKey
. Я исправил ваш фрагмент кода:
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
Что насчет х86 на х64? Используйте 64-битные специальные типы
Что, если в "Удалить" имеется более 1024 подразделов? Используйте _winreg.QueryInfoKey (ключ)
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 does not 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 does not exist in this skey
pass
finally:
skey.Close()
Ответ 3
Как говорится в документации _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
Ответ 4
Я упростил функциональность _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
Ответ 5
Сделана простая программа для вывода списка подключей в реестре. в настоящее время пытаются выяснить, как искать в этом списке определенные подразделы, а затем добавить их, если их там нет, и/или изменить значение. (не должно быть слишком сложно)
Это то, что я придумал. Я надеюсь, что это помогает, также не стесняйтесь критиковать это:
from winreg import *
registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
def openRegistryA():
rawKeyA = OpenKey(registry, "SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")
try:
i = 0
while 1:
name, value, type = EnumValue(rawKeyA, i)
print(name, value, i)
i += 1
except WindowsError:
print("END")
CloseKey(rawKeyA)
def openRegistryB():
rawKeyB = OpenKey(registry, "SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters")
try:
i = 0
while 1:
name, value, type = EnumValue(rawKeyB, i)
print(name, value, i)
i += 1
except WindowsError:
print("END")
CloseKey(rawKeyB)
openRegistryA()
openRegistryB()