QDA QDA - 4 months ago 22
Python Question

Opens same registry twice?

I am trying to get all installed programs of my windows computer, therefore I read out the registry.

But somehow python reads the 32bit programs out twice (even though I give him another registry entry)

Here is the code snipped:

def get_programs(registry):
reg = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
programList = []

key = OpenKey(reg, registry)
print(QueryInfoKey(key))
for i in range(0, QueryInfoKey(key)[0]):
programList.append(EnumKey(key, i))
CloseKey(key)
CloseKey(reg)
return programList


I call this function like this:

registry32bit = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
registry64bit = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
programs32bit = get_programs(registry32bit)
programs64bit = get_programs(registry64bit)


Why does python open and read out the same registry (for 32 bit) twice and return the exactly same list?

Answer

This appears to work and use @eryksun suggestion in a comment below about just letting the redirection happen and not explicitly referencing the Wow6432Node key. The core idea is to just specify either the KEY_WOW64_32KEY or KEY_WOW64_64KEY flag when opening the subkey and let the magic happen.

Note: I also "Pythonized" the code in the get_programs() function a bit which included adding a context manager helper function to automate the closing of open registry items. It makes the function itself shorter as well as more readable in my opinion.

from contextlib import contextmanager
from _winreg import *

@contextmanager
def reg_context(handle):
    yield handle
    CloseKey(handle)

def get_programs(subkey, regBitView):
    with reg_context(ConnectRegistry(None, HKEY_LOCAL_MACHINE)) as hive:
        with reg_context(OpenKey(hive, subkey, 0, regBitView | KEY_READ)) as key:
            return [EnumKey(key, i) for i in range(QueryInfoKey(key)[0])]

UNINSTALL_REG_KEY = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
programs32bit = get_programs(UNINSTALL_REG_KEY, KEY_WOW64_32KEY)
programs64bit = get_programs(UNINSTALL_REG_KEY, KEY_WOW64_64KEY)

print('32-bit programs:\n{}'.format(programs32bit))
print('')
print('64-bit programs:\n{}'.format(programs64bit))

Many thanks to @eryksun for the clues and suggested implementation strategy.