Problem with python, COM and multithreading

I am trying to take a look at the IE DOM from a separate thread that IE sent, and for some properties I get a "no such interface" error. I managed to reduce the problem to this script:

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() 

Everything is fine until frame.contentWindow . Then 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) 

Any clues?

+6
source share
1 answer

The correct answer is to marshal manually. This is not a workaround you should do here. However, you do not need to use a thread in the apartment.

You initialized as a multi-threaded apartment that tells COM that it can call your interfaces in any thread. It does not allow you to call other interfaces in any thread or excuse you from the marshalling interfaces provided by COM. This will work "randomly" - for example. if the object you are calling is an MTA object in the process, it does not matter.

CoMarshalInterThreadInterfaceInStream / CoGetInterfaceAndReleaseStream doing business.

The reason for this is that objects can provide their own proxies, which may or may not be free. (Or, indeed, provide individual sorting). You must march them to tell them that they are moving between the threads. If the proxy server is free, you can return the same pointer.

+1
source

Source: https://habr.com/ru/post/904983/


All Articles