Импорт pywinauto (или comtypes) забивает существующий COM-объект - PullRequest
0 голосов
/ 13 сентября 2018

Создание / получение COM-объекта с использованием win32com.client.GetActiveObject, а затем import pywintypes приводит к AttributeError при каждом вызове исходного COM-объекта.

Код для воспроизведения

import win32com.client
catia_com = win32com.client.GetActiveObject('CATIA.Application')

# then later when needed, do some pywinauto stuff
import pywinauto.application

# back to working directly on catia com object
print(catia.caption)  # raises Attribute error from within win32com.client

Почему это происходит и как это можно исправить?

1 Ответ

0 голосов
/ 13 сентября 2018

Мне удалось найти решение для этого, которым я хотел бы поделиться, но я также хотел бы услышать отзывы о моем понимании и какова соответствующая зависимость, где это должно быть устранено, чтобы другие люди не имели такой же проблемы .

Решение

Добавьте import comtypes перед вызовом win32com.client.

Пример

import comtypes
import win32com.client
catia_com = win32com.client.GetActiveObject('CATIA.Application')

# then later when needed, do some pywinauto stuff
import pywinauto.application

# back to working directly on catia com object
print(catia.caption)  # it works!

Причина и объяснение (насколько я могу определить)

TLDR

import comtypes вызывает CoInitializeEx с флагом COINIT_MULTITHREADED, который переопределяет режим, установленный win32com.client.GetActiveObject.

Полное объяснение

Я пришел к такому выводу, потому что при комментировании pythoncom.CoUninitialize() (я беспокоился, что он убивает COM-объект, возвращенный из win32com.client.GetActiveObject) в pywinauto.__init__ и при повторном запуске кода, из comtypes.__init__ возникла следующая ошибка:

OSError: [WinError -2147417850] Cannot change thread mode after it is set

Я знаю, что comtypes.__init__ управляет выбором флагов по умолчанию для CoInitializeEx и не может определить, какова библиотека win32com, но полагает, что она также, вероятно, проверяет существующие флаги, поэтому я добавил import comtypes.

Где я все еще неясен

  1. Как определить флаги модели параллелизма для win32com?
  2. Как указать флаги модели параллелизма при вызове win32com.client.GetActiveObject?
  3. Почему именно решение работает ... вызов pythoncom.CoInitializeEx(0x0) прямо перед вызовом win32com.client.GetActiveObject не работает!

Если я смогу ответить на вышеизложенное, я могу порекомендовать win32com установить sys.coinit_flags (именно здесь comtypes.__init__ проверяет).

Rescources

...