2016-08-01 4 views
1

Я пытаюсь получить все установленные программы моего компьютера Windows, поэтому я зачитал реестр.Открывает тот же реестр дважды?

Но как-то питон читает программу 32bit дважды (даже если я дам ему еще один параметр реестра)

Вот код отрезал:

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 

Я называю эту функцию следующим образом:

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

Почему python открывает и считывает один и тот же реестр (для 32 бит) дважды и возвращает точно такой же список?

+0

вы можете использовать некоторые инструменты отладки, такие как 'pdb' или просто используя' print'. Отладка по очереди, чтобы проверить, что ваш код работает нормально или нет. –

+0

Я уже использовал инструмент отладки от pycharm :( – QDA

+1

И? Вы что-нибудь нашли? Эта функция 'QueryInfoKey (key)' вызывается дважды. Попробуйте прокомментировать 'print (QueryInfoKey (key))' –

ответ

1

Это, как представляется, работает и использует предложение @eryksun в комментарии ниже о простом разрешении перенаправления и не явным образом ссылается на раздел реестра Wow6432Node. Основная идея состоит в том, чтобы просто указать флаг KEY_WOW64_32KEY или KEY_WOW64_64KEY при открытии раздела деинсталляции и позволить магии произойти.

Примечание: Я также Pythonized код в get_programs() функция некоторые. Это сделало его более коротким и читаемым, на мой взгляд.

import sys 
from _winreg import * 

# Assure registry handle objects with context manager protocol implemented. 
if sys.version_info.major*10 + sys.version_info.minor < 26: 
    raise AssertionError('At least Python 2.6 is required.') 

def get_programs(subkey, regBitView): 
    with ConnectRegistry(None, HKEY_LOCAL_MACHINE) as hive: 
     with 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)) 

Большое спасибо @eryksun за подсказки и многие рекомендации по реализации стратегии.

+0

Просто используйте 'r 'SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall" '. Разрешить фильтру перенаправления использовать свою магию на основе флага в нужном доступе. Диспетчер ввода/вывода Windows (например, устройства и файловые системы) и диспетчер конфигурации (например, реестр) накладываются друг на друга, чтобы позволить драйверам фильтров изменять операции «на лету».У WOW64 есть драйверы фильтров для автоматического перенаправления доступа к реестру и файловой системе. Это другой подход к тому, как MultiArch реализуется в Linux, потому что проблема связана с жестко закодированными путями в программных джунглях Windows. – eryksun

+0

@eryksun: Хорошая точка (и объяснение) - обновил мой ответ соответственно. Еще раз спасибо. – martineau

+0

ключи winreg (или 2.x _winreg) являются [уже контекстными менеджерами] (https://hg.python.org/cpython/file/v2.7.12/PC/_winreg.c#l582) (источник 2.7.12), который поддержка закрытия в блоке 'с'. – eryksun

Смежные вопросы