python,COM和多线程问题

fra*_*ca7 6 python com internet-explorer automation

我试图从调度IE的单独线程看一下IE的DOM,对于某些属性我得到"没有这样的接口支持"错误.我设法将问题减少到这个脚本:

import threading, time

import pythoncom
from win32com.client import Dispatch, gencache
gencache.EnsureModule('{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}', 0, 4, 0) # MSHTML

def main():
    pythoncom.CoInitializeEx(0)
    ie = Dispatch('InternetExplorer.Application')
    ie.Visible = True
    ie.Navigate('http://www.Rhodia-ecommerce.com/')
    while ie.Busy:
        time.sleep(1)

    def printframes():
        pythoncom.CoInitializeEx(0)
        document = ie.Document
        frames = document.getElementsByTagName(u'frame')
        for frame in frames:
            obj = frame.contentWindow

    thr = threading.Thread(target=printframes)
    thr.start()
    thr.join()

if __name__ == '__main__':
    thr = threading.Thread(target=main)
    thr.start()
    thr.join()
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到frame.contentWindow.然后bam:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "C:\python22\lib\threading.py", line 414, in __bootstrap
    self.run()
  File "C:\python22\lib\threading.py", line 402, in run
    apply(self.__target, self.__args, self.__kwargs)
  File "testie.py", line 42, in printframes
    obj = frame.contentWindow
  File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 455, in __getattr__
    return self._ApplyTypes_(*args)
  File "C:\python22\lib\site-packages\win32com\client\__init__.py", line 446, in _ApplyTypes_
    return self._get_good_object_(
com_error: (-2147467262, 'No such interface supported', None, None)
Run Code Online (Sandbox Code Playgroud)

任何提示?

Ben*_*Ben 1

正确的答案是手动整理东西。这不是解决方法,而是您应该在这里执行的操作。不过,您不必使用公寓线程。

您初始化为多线程单元 - 它告诉 COM可以在任何线程上调用您的接口。它不允许在任何线程上调用其他接口,也不允许您编组 COM 提供的接口。这只会“偶然”起作用 - 例如,如果您正在调用的对象恰好是进程内 MTA 对象,则没关系。

CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream做生意。

这样做的原因是对象可以提供自己的代理,该代理可能是也可能不是自由线程的。(或者确实提供自定义编组)。您必须编组它们以告诉它们正在线程之间移动。如果代理是自由线程的,您可能会得到相同的指针。