首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pythoncom在Python进程之间封送COM对象

使用pythoncom在Python进程之间封送COM对象
EN

Stack Overflow用户
提问于 2014-04-04 13:03:00
回答 1查看 2.2K关注 0票数 4

我希望有人能帮助我从Python中对Excel进行封送处理的跨进程调用。

我有一个通过Python启动的Excel会话,当需要从单独的Python进程访问它时,它将启动并运行。使用来自pythoncom模块的CoMarshalInterfaceInStream()CoGetInterfaceAndReleaseStream()调用进行封送处理,一切都可以正常工作,但我需要重复访问流(在我的情况下只能设置一次),CoGetInterfaceAndReleaseStream()只允许访问接口一次。

我相信,我想要实现的目标可以用CreateStreamOnHGlobal()CoMarshalInterface()CoUnmarshalInterface()来完成,但是无法工作,这几乎肯定是因为我没有传递正确的参数。

我没有详细描述我的主要场景,而是设置了一个简单的示例程序,如下所示--很明显,这是在相同的过程中发生的,但一步一步!以下代码片段工作正常:

代码语言:javascript
复制
import win32com.client
import pythoncom

excelApp = win32com.client.DispatchEx("Excel.Application")

marshalledExcelApp = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, excelApp)

xlApp = win32com.client.Dispatch(
                                pythoncom.CoGetInterfaceAndReleaseStream(marshalledExcelApp, pythoncom.IID_IDispatch))

xlWb = xlApp.Workbooks.Add()
xlWs = xlWb.Worksheets.Add()
xlWs.Range("A1").Value = "AAA"

但是,当我尝试以下几点时:

代码语言:javascript
复制
import win32com.client
import pythoncom

excelApp = win32com.client.DispatchEx("Excel.Application")

myStream = pythoncom.CreateStreamOnHGlobal()                                   
pythoncom.CoMarshalInterface(myStream,
                             pythoncom.IID_IDispatch,
                             excelApp,
                             pythoncom.MSHCTX_LOCAL,
                             pythoncom.MSHLFLAGS_TABLESTRONG)   

myUnmarshaledInterface = pythoncom.CoUnmarshalInterface(myStream, pythoncom.IID_IDispatch)

我在调用pythoncom.CoMarshalInterface()时得到了这个错误(我想这与第三个参数有关)

代码语言:javascript
复制
"ValueError: argument is not a COM object (got type=instance)"

有人知道我怎样才能让这个简单的例子奏效吗?

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2014-04-11 13:28:23

经过许多忧虑后,我设法解决了我所面临的问题,甚至是随后的问题,我也将对这些问题进行描述。

首先,我猜对了,我最初的问题是调用pythoncom.CoMarshalInterface()中的第三个参数。实际上,我应该引用我的excelApp变量的oleobj属性:

代码语言:javascript
复制
pythoncom.CoMarshalInterface(myStream, 
                             pythoncom.IID_IDispatch, 
                             excelApp._oleobj_, 
                             pythoncom.MSHCTX_LOCAL, 
                             pythoncom.MSHLFLAGS_TABLESTRONG)

但是,我随后遇到了一个不同的错误消息,这次是在调用pythoncom.CoUnmarshalInterface()时:

代码语言:javascript
复制
com_error: (-2147287010, 'A disk error occurred during a read operation.', None, None)

结果表明,这是因为流指针需要在使用前用with ()方法重置:

代码语言:javascript
复制
myStream.Seek(0,0) 

最后,尽管大多数方面都正常工作,但我发现,尽管在封送Excel对象上使用了Quit(),并且在代码结束之前显式地将所有变量设置为None,但我还是留下了一个僵尸Excel进程。这是尽管pythoncom._GetInterfaceCount()返回0。

结果,我不得不通过调用CoReleaseMarshalData()显式地清空我创建的流(第一次重置流指针)。因此,完整的示例代码片段如下所示:

代码语言:javascript
复制
import win32com.client
import pythoncom

pythoncom.CoInitialize()

excelApp = win32com.client.DispatchEx("Excel.Application")

myStream = pythoncom.CreateStreamOnHGlobal()    
pythoncom.CoMarshalInterface(myStream, 
                             pythoncom.IID_IDispatch, 
                             excelApp._oleobj_, 
                             pythoncom.MSHCTX_LOCAL, 
                             pythoncom.MSHLFLAGS_TABLESTRONG)    

excelApp = None

myStream.Seek(0,0)
myUnmarshaledInterface = pythoncom.CoUnmarshalInterface(myStream, pythoncom.IID_IDispatch)    
unmarshalledExcelApp = win32com.client.Dispatch(myUnmarshaledInterface)

# Do some stuff in Excel in order to prove that marshalling has worked. 
unmarshalledExcelApp.Visible = True
xlWbs = unmarshalledExcelApp.Workbooks
xlWb = xlWbs.Add()
xlWss = xlWb.Worksheets
xlWs = xlWss.Add()
xlRange = xlWs.Range("A1")
xlRange.Value = "AAA"
unmarshalledExcelApp.Quit()    

# Clear the stream now that we have finished
myStream.Seek(0,0)
pythoncom.CoReleaseMarshalData(myStream)

xlRange = None
xlWs = None
xlWss = None
xlWb = None
xlWbs = None
myUnmarshaledInterface = None
unmarshalledExcelApp = None
myStream = None

pythoncom.CoUninitialize()

我希望这能帮助别人克服我所面临的障碍!

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22863646

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档