[python-win32] COM and threading
Tim Golden
mail at timgolden.me.uk
Fri Jun 27 17:56:52 CEST 2008
June Kim wrote:
> Running the following code results in an attribute error:
>
> Exception in thread Thread-1:
> Traceback (most recent call last):
> File "C:\Python25\lib\threading.py", line 486, in __bootstrap_inner
> self.run()
> File "testcom.py", line 10, in run
> print self.ie.locationUrl
> File "C:\Python25\Lib\site-packages\win32com\client\dynamic.py", line 500, in
> __getattr__
> raise AttributeError, "%s.%s" % (self._username_, attr)
> AttributeError: InternetExplorer.Application.locationUrl
>
> It seems like the COM object isn't properly passed to the new thread.
> Any roundabouts?
Welcome to the wonderful world of COM and threading. Basically,
the IWebBrowser2 object which is behind the InternetExplorer
control cannot be passed as such between threads. To pass it
between threads you need to marshal it and pass the resulting
istream to the other thread which will then unmarshal it again.
There's some sample code below which does this, but you might
want to consider another approach, depending on what your app
is trying to do, such as creating an IE object per thread and/or
passing native Python objects between threads with Queues etc.
TJG
<code>
import os, sys
import threading
import time
import pythoncom
import win32com.client
class Work (threading.Thread):
def __init__ (self, marshalled_ie):
threading.Thread.__init__ (self)
self.marshalled_ie = marshalled_ie
def run (self):
pythoncom.CoInitialize ()
ie = win32com.client.Dispatch (
pythoncom.CoGetInterfaceAndReleaseStream (
self.marshalled_ie,
pythoncom.IID_IDispatch
)
)
print "Threaded LocationURL:", ie.LocationURL
pythoncom.CoUninitialize ()
ie = win32com.client.Dispatch ("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate ("http://python.org")
while ie.Busy:
time.sleep (1)
print "LocationURL:", ie.LocationURL
marshalled_ie = pythoncom.CoMarshalInterThreadInterfaceInStream (
pythoncom.IID_IDispatch, ie
)
work = Work (marshalled_ie)
work.start ()
work.join ()
ie.Quit ()
</code>
More information about the python-win32
mailing list