win32com.client.DispatchWithEvents不捕获事件并抛出异常

0 投票
1 回答
3021 浏览
提问于 2025-04-18 13:32

我需要连接到一个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!

我检查了DispatchDispatchWithEvents实际返回的对象是什么:

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 个回答

1

试着通过 DispatchWithEvents 连接到 Excel,并触发一些事件(可以查看网上的 Excel 互操作文档),看看你的监听器是否能接收到这些事件。如果能接收到,那说明你的 COM 对象可能有问题,或者你需要生成类型库。你可以先用 EnsureDispatch 来使用你的对象,这个步骤只需要做一次。之后,看看用 DispatchWithEvents 后,你的 Python 对象是否仍然缺少 MyMethod1 等方法。如果没有缺少,并且 Excel(或者其他高质量的 COM 服务器,比如 Word 或 IE)的事件都能正常工作,那就说明你的 COM 对象一定有问题。

撰写回答