Python code to read registry

Question:

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
Asked By: Vinod K

||

Answers:

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
Answered By: Velociraptors

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:

import winreg
aReg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
print(r"*** Reading from %s ***" % aKey)

aKey = winreg.OpenKey(aReg, r'SOFTWAREMicrosoftWindowsCurrentVersionUninstall')
for i in range(1024):
    try:
        aValue_name = winreg.EnumKey(aKey, i)
        oKey = winreg.OpenKey(aKey, aValue_name)
        sValue = winreg.QueryValueEx(oKey, "DisplayName")
        print(sValue)
    except EnvironmentError:
        break

Please note, that not every key has "DisplayName" value available.

Answered By: yurymik

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()
Answered By: VertigoRay

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

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()
Answered By: Eric Witt
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.