Python code to read registry

from _winreg import *

"""print r"*** Reading from SOFTWAREMicrosoftWindowsCurrentVersionRun ***" """
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)

aKey = OpenKey(aReg, r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall")
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 HKLMSOFTWAREMicrosoftWindowsCurrentVersionUninstall
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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 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 *

aKey = r"SOFTWAREMicrosoftWindowsCurrentVersionUninstall"
aReg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)

print(r"*** Reading from %s ***" % aKey)

aKey = OpenKey(aReg, aKey)
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.

Method 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"SOFTWAREMicrosoftWindowsCurrentVersionUninstall", 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"SOFTWAREMicrosoftWindowsCurrentVersionUninstall", 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()

Method 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"SOFTWAREMicrosoftWindowsCurrentVersionUninstall")
for i in range(1024):
    try:
        keyname = EnumKey(aKey, i)
        asubkey = OpenKey(aKey, keyname)
        val = QueryValueEx(asubkey, "DisplayName")
        print val
    except WindowsError:
        break

Method 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_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall'

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

Method 5

Made a simple program to produce a list of the subkeys in the registry. Currently, trying to figure out how to search that list for specific subkeys and then add them if they are not there, and/or change the value. (shouldn’t be too difficult)
This is what I came up with. I hope it helps, also feel free to critique it:

from winreg import *

registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
def openRegistryA():

    rawKeyA = OpenKey(registry, "SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem")

    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, "SYSTEMCurrentControlSetServicesLanmanServerParameters")

    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()


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x