经过多次焦虑后,我成功解决了我面临的问题,以及我将描述的后续问题。
首先,我正确地猜测我最初的问题是调用 pythoncom.CoMarshalInterface() 中的第三个参数。事实上,我应该参考一下oleobj我的 excelApp 变量的属性:
pythoncom.CoMarshalInterface(myStream,
pythoncom.IID_IDispatch,
excelApp._oleobj_,
pythoncom.MSHCTX_LOCAL,
pythoncom.MSHLFLAGS_TABLESTRONG)
然而,我随后遇到了不同的错误消息,这次是在调用 pythoncom.CoUnmarshalInterface() 时:
com_error: (-2147287010, 'A disk error occurred during a read operation.', None, None)
事实证明,这是由于流指针需要在使用前使用 Seek() 方法重置:
myStream.Seek(0,0)
最后,虽然大多数方面都工作正常,但我发现尽管在编组的 Excel 对象上使用 Quit() 并在代码结束之前将所有变量显式设置为 None,但我仍然留下了一个僵尸 Excel 进程。尽管事实上 pythoncom._GetInterfaceCount() 返回了 0。
事实证明,我必须显式清空通过调用 CoReleaseMarshalData() 创建的流(首先再次重置流指针)。因此,整个示例代码片段如下所示:
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()
我希望这可以帮助其他人克服我所面临的障碍!