Непредвиденная ошибка COM (-2147352567, ‘Произошло исключение.’, (0, u’SWbemProperty’, u’Несоответствие типа) при чтении реестра Windows на Python

Вопрос или проблема

Какую программу я мог бы использовать, чтобы получить список установленного программного обеспечения, используя Python для разных платформ или как минимум Windows или Mac? Пожалуйста, проверьте код, который я нашел в интернете, но у меня возникают ошибки. Я использую Python 2.7, Win 7 64 бита, Eclipse

import StringIO
import traceback    
import wmi
from _winreg import (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, 
                     OpenKey, EnumValue, QueryValueEx)

softFile = open('softLog.log', 'w')
errorLog = open('errors.log', 'w')

r = wmi.Registry ()
result, names = r.EnumKey (hDefKey=HKEY_LOCAL_MACHINE, sSubKeyName=r"Software\Microsoft\Windows\CurrentVersion\Uninstall")

softFile.write('Эти подчиненные ключи найдены в "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"\n\n')
errorLog.write("Ошибки\n\n")
separator = "*" * 80
keyPath = r"Software\Microsoft\Windows\CurrentVersion\Uninstall"

for subkey in names:
    try:
        softFile.write(separator + '\n\n')
        path = keyPath + "\\" + subkey
        key = OpenKey(HKEY_LOCAL_MACHINE, path, 0, KEY_ALL_ACCESS) 
        try:
            temp = QueryValueEx(key, 'DisplayName')
            display = str(temp[0])
            softFile.write('Display Name: ' + display + '\nRegkey: ' + subkey + '\n')
        except:
            softFile.write('Regkey: ' + subkey + '\n')

    except:
        fp = StringIO.StringIO()
        traceback.print_exc(file=fp)
        errorMessage = fp.getvalue()
        error="Ошибка для " + key + '. Сообщение далее:\n' + errorMessage
        errorLog.write(error)
        errorLog.write("\n\n")

softFile.close()/* файлы пустые*/
errorLog.close()

Ошибка, отображаемая в консоли:

Traceback (most recent call last):
  File "C:\Users\Administrator\EclipseWorkspace\Aug28th2012\PythonDevelopment\src\TestClass\Hii.py", line 21, in <module>
    result, names = r.EnumKey (hDefKey=HKEY_LOCAL_MACHINE, sSubKeyName=r"Software\Microsoft\Windows\CurrentVersion\Uninstall")
  File "C:\Python27\lib\site-packages\wmi.py", line 431, in __call__
    handle_com_error ()
  File "C:\Python27\lib\site-packages\wmi.py", line 241, in handle_com_error
    raise klass (com_error=err)
wmi.x_wmi: <x_wmi: Неожиданная ошибка COM (-2147352567, 'Произошло исключение.', (0, u'SWbemProperty', u'Несоответствие типов ', None, 0, -2147217403), None)>

Понятие установленного программного обеспечения не до конца определенно, так как на Windows процесс установки является свободной формой на некрытых платформах (iOS, Android).

Возможные варианты

  • Чтение установленных приложений с использованием Windows API

  • Список папок в C:\Program Files

  • На OSX “установленное приложение” – это содержимое папки /Applications

Если вы хотите проверить конкретное приложение, то читайте его связанную запись об установке (конкретную для приложения) из реестра Windows.

См. мой ответ здесь:
https://stackoverflow.com/questions/34329073/executing-wmi-registry-enumkey-gives-type-mismatch-error/40363864#40363864

В основном, это кажется проблемой с константами _winreg и 64-битным Python.

Ответ или решение

Профессиональный Разbor Ошибки и Решения

Ошибка, с которой вы столкнулись в вашем коде на Python 2.7, связана с использованием COM-интерфейсов Windows Management Instrumentation (WMI) и чтением из реестра Windows. Ошибка COM под кодом -2147352567 обычно указывает на "ошибку несоответствия типов", что является распространенной проблемой в подобных сценариях. Давайте разберемся подробнее с ошибкой и рассмотрим, как можно решить данную проблему.

Контекст и Предложенные Решения

Вы пытаетесь получить список установленных программ на системе Windows через Python. Это осуществляется с использованием библиотеки wmi и доступа к реестру Windows через модуль _winreg. Давайте начнем с разбора вашей задачи и далее перейдем к возможным решениям.

  1. Ошибка COM и WMI: Ошибка типа, которую вы видите, указывает на несовпадение ожидаемого и фактического типа данных в одном из свойств COM-объекта при вызове функции EnumKey. Это может происходить из-за различий в управлении 32-разрядными и 64-разрядными версиями Python и ОС.

  2. Кроссплатформенность: Учитывая ваш вопрос о кроссплатформенности, вам может понадобиться рассмотреть альтернативные подходы, такие как использование более современных языков, библиотек или инструментов, которые лучше поддерживают кроссплатформенность.

Рекомендации по Решению Проблемы

  1. Перейти на Более Современную Версию Python: Python 2.7 больше не поддерживается. Рекомендуется обновить текущее рабочее окружение до Python 3.x. Новейшие версии содержат улучшения и поддержку современных библиотек, которые помогут устранить многие проблемы совместимости.

  2. Использование ctypes или pywin32: Вместо использования wmi, можно применить ctypes или pywin32, которые обеспечивают прямой доступ к API Windows, избегая ошибок в COM-интерфейсах.

  3. Проверка Архитектуры: Убедитесь, что ваша Python-интерпретатор совпадает с архитектурой вашей ОС (оба должны быть 64-разрядными).

  4. Альтернативные Инструменты: Для кроссплатформенных решений, таких как получение информации об установленных приложениях на Mac, используйте модули os и subprocess для выполнения shell-команд, которые листают содержимое каталога /Applications.

  5. Использование библиотеки winreg в Python 3: Если вы всё же решите остаться с работой в Windows, библиотека winreg в Python 3.х предоставляет более надежное API для работы с реестром, чем устаревший _winreg из Python 2.7.

Конкретные Изменения в Коде

Поскольку у вас проблемы с версией Python и архитектурой, рекомендуется следующее:

# Пример на Python 3
import winreg

try:
    softFile = open('softLog.log', 'w')
    errorLog = open('errors.log', 'w')

    key_path = r"Software\Microsoft\Windows\CurrentVersion\Uninstall"
    with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path) as key:
        for i in range(0, winreg.QueryInfoKey(key)[0]):
            subkey_name = winreg.EnumKey(key, i)
            try:
                with winreg.OpenKey(key, subkey_name) as subkey:
                    try:
                        display_name = winreg.QueryValueEx(subkey, 'DisplayName')[0]
                        softFile.write(f'Display Name: {display_name}\nRegkey: {subkey_name}\n')
                    except FileNotFoundError:
                        pass
            except Exception as e:
                errorLog.write(f"Error with {subkey_name}: {str(e)}\n")

    softFile.close()
    errorLog.close()
except Exception as e:
    print(f"Unexpected error: {str(e)}")

По завершении замены устаревшего кода и перехода на современные версии Python и инструменты, вам удастся избежать многих проблем как при разработке на Windows, так и при переходе на кроссплатформенные решения.

Оцените материал
Добавить комментарий

Капча загружается...