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

może ktoś proszę poprawić błąd ... ja po prostu chcę, aby wyświetlić „DisplayName” w podkluczy klucza w HKLM \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall Jest błąd pojawia ..kod Pythona do odczytu rejestru

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

Btw, kiedy widzisz taki błąd, to jest coś th, aby wypróbować 'print (type (asubkey) .__ name __)', aby zorientować się, z czym masz do czynienia. – yurymik

Odpowiedz

24

Documentation mówi, że EnumKey zwrotów napis z nazwą klucz jest. Musisz jawnie otworzyć go za pomocą funkcji _winreg.OpenKey. Poprawiłem Twój fragment kodu:


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 

Uwaga: nie każdy klawisz ma wartość "DisplayName".

+2

Nie musisz podawać pełnej ścieżki do klucza, jeśli użyjesz klawisza otwierającego jako pierwszego parametru, gdy wywołasz 'OpenKey'. – Velociraptors

+1

Tak, masz rację. Naprawiony. – yurymik

+2

to nie daje wyjścia .. –

5

Jak mówi w dokumentacji _winreg.QueryValueEx, trzeba zdać już otwarty klucz. EnumKey zwraca ciąg znaków, a nie klawisz otwarty.

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

Co z x86 na x64? Use 64-bit Specific Types

Co się stanie, jeśli w "Odinstaluj" jest więcej niż 1024 podkluczy? 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

Pomija ostatni wpis, parametr zatrzymania dla xrange jest wyłączny. – CrouZ

+1

Dzięki, upuściłem "-1", ponieważ zakładam, że o tym mówisz. – VertigoRay

+2

Należy pamiętać, że% PROCESSOR_ARCHITECTURE% zwraca x86 z 32-bitowym pythonem, nawet jeśli system operacyjny jest 64-bitowy. –

1

I uproszczone _winreg funkcjonalność zapytań zagnieżdżonych wartości danego klucza rejestru.

Na przykład, to jak prosta jest do kwerendy klucz rejestru zapytany o:

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 

wyjście

{'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'} 
... 

dodać te funkcje użytkowe, a także:

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

Dziękuję, to działa. Ale w jaki sposób chciałbym uzyskać wartości dla określonego podklucza?Jeśli przejdę do konkretnego programu (dla zmiennej kluczowej) w katalogu "Odinstaluj", na przykład nic nie zostanie zwrócone. – Sensei

Powiązane problemy