win32com.client.DispatchWithEvents не перехватывает события и вызывает исключение

Мне нужно подключиться к COM-интерфейсу (конкретная реализация), вызвать некоторые методы, получить ответы как синхронно, так и асинхронно. Мне пришлось замаскировать некоторые конкретные имена интерфейсов/методов при вставке примеров кода. Если я использую только метод Dispatch, все работает нормально:

#works fine in synchronous mode
myObj = win32com.client.Dispatch(myObjID)
myObj.MyMethod1(0)
myResp = myObj.myMethod2()
print "property1: " + myResp.property1 #works fine

Проблема начинается, когда мне нужно получить некоторые события (DispatchWithEvents). Это приводит к сбою Python! Возникает сетевое исключение низкого уровня: exceptions.EOFError: [Errno 10054] Существующее соединение было принудительно закрыто удаленным хостом. Пример кода, который приводит к сбою:

#crashing code
class SomeEvents(object):
    def OnMethod1(self):
        print 'OnMethod1'

myObj = win32com.client.DispatchWithEvents(myObjID,SomeEvents)
myObj.MyMethod1(0) # CRASH OCCURS HERE!

Я проверил, какой объект на самом деле возвращается Dispatch и DispatchWithEvents:

Объект, возвращенный Dispatch:

<win32com.gen_py.myComInterface 1.0 Type Library.myComManager instance at 0x20508304>
['CLSID', 'MyMethod1', 'MyMethod2', 'MyMethod3', 'MyMethod4', 'MyMethod5', '_ApplyTypes_', '__doc__', '__eq__', '__getattr__', '__init__', '__iter__', '__module__', '__ne__', '__repr__', '__setattr__', '_get_good_object_', '_get_good_single_object_', '_oleobj_', '_prop_map_get_', '_prop_map_put_', 'coclass_clsid']

Объект, возвращаемый DispatchWithEvents:

<win32com.client.COMEventClass instance at 0x20462352>
['__del__', '__doc__', '__getattr__', '__init__', '__module__', '__setattr__', '_obj_']

В обоих случаях возвращаются объекты разных типов. Объект, возвращаемый DispatchWithEvents, является COMEventClass и не содержит MyMethod1, MyMethod2 и т. д. (является ли это причиной сбоя? Я ожидаю, что исключение "Объект не имеет атрибута")

Я также попытался реализовать это, создав 2 разных объекта. В результате не происходит сбоя, но и не перехватываются события. Пример кода:

#doesn't crash but also doesn't catch any events
class SomeEvents(object):
    def OnMethod1(self):
        print 'OnMethod1'

myObj1 = win32com.client.Dispatch(myObjID)
myObj2 = win32com.client.DispatchWithEvents(myObjID,SomeEvents)
myObj1.MyMethod1(0) 
myResp = myObj1.MyMethod2()
print "property1: " + str(myResp.property1) #property displayed correctly
#no 'OnMethod1' printout visible

Я реализовывал COM-клиент, используя примеры, найденные в Интернете. Версия Python: 2.7.6 (32-разрядная версия) на WinXP SP3. Я не смог найти подобную проблему (что меня немного удивило). Что я делаю не так? Возможно, в конкретной реализации COM есть ошибки? Я думаю, что следующим шагом будет реализация COM-клиента с использованием VB и проверка на наличие подобных проблем. Что ты предлагаешь?


person Marcin Kowalczyk    schedule 16.07.2014    source источник


Ответы (1)


Попробуйте подключиться к Excel через DispatchWithEvents и инициировать некоторые события (посмотрите онлайн-документацию по взаимодействию с Excel) и посмотрите, получит ли их ваш слушатель. Если это работает, значит, что-то не так с вашим COM-объектом, или вам, возможно, придется сгенерировать библиотеку типов. Вы можете сделать это, сначала используя свой объект с EnsureDispatch, вам нужно сделать это только один раз. После этого проверьте, не используется ли DispatchWithEvents ваш объект Python, по-прежнему отсутствует MyMethod1 и т. д. Если нет, и события COM-экземпляра Excel (или любого другого COM-сервера производственного качества, такого как Word или IE) работают, значит, что-то не так с вашим COM-объектом. .

person Oliver    schedule 18.07.2014
comment
Спасибо за подсказки. Я пробовал их, но мой сценарий все еще терпит неудачу. Мне удалось получить события от COM-объекта Internet Explorer. Я также подозреваю, что с COM-объектом может быть что-то не так. - person Marcin Kowalczyk; 18.07.2014
comment
Согласен, это единственный разумный вывод на данный момент. Я полагаю, вы читали страницы MSDN о COM API и события? - person Oliver; 18.07.2014