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等(这会导致崩溃吗?我本来期待的是“对象没有这个属性”的异常)
我还尝试通过创建两个不同的对象来实现它。结果是没有崩溃,但也没有捕获到任何事件。代码示例:
#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的特定实现有bug?我觉得下一步应该用VB实现COM客户端,看看是否有类似的问题。你有什么建议?
1 个回答
试着通过 DispatchWithEvents
连接到 Excel,并触发一些事件(可以查看网上的 Excel 互操作文档),看看你的监听器是否能接收到这些事件。如果能接收到,那说明你的 COM 对象可能有问题,或者你需要生成类型库。你可以先用 EnsureDispatch
来使用你的对象,这个步骤只需要做一次。之后,看看用 DispatchWithEvents
后,你的 Python 对象是否仍然缺少 MyMethod1
等方法。如果没有缺少,并且 Excel(或者其他高质量的 COM 服务器,比如 Word 或 IE)的事件都能正常工作,那就说明你的 COM 对象一定有问题。