Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Python 2.1, COM (Excel), and Threads...

175 views
Skip to first unread message

Stephen

unread,
Oct 31, 2002, 1:31:03 PM10/31/02
to
Hi -

I am trying to get a threaded job server running that will thread
scripts to manipulate various MS office apps. My first attempt has
failed on Excel. It seems that invoking
win32com.client.Dispatch('Excel.Application') from within a thread
does not initialize the same way as it does when it is called from
within the main python environment. A simple example:

from threading import Thread

class foo:
def run(self):
try:
import win32com.client
self.excel = win32com.client.Dispatch("Excel.Application")
self.excel.Visible = 1
k = self.excel.Workbooks.Add()
v = k.Worksheets(1)
v.Cells(1,1).Value = str(self)
except:
import traceback
traceback.print_exc()

l = Thread(target = foo().run, #creates a new instance
name = 'foo',verbose = 1)
l.start()

This causes the following stack trace:

Traceback (most recent call last):
File "I:\F\P\sp\interfaces\dispatcher\testexcelinthread.py", line
18, in run
self.excel = win32com.client.Dispatch("Excel.Application")
File "d:\python21\win32com\client\__init__.py", line 94, in Dispatch
dispatch, userName =
dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "d:\python21\win32com\client\dynamic.py", line 81, in
_GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "d:\python21\win32com\client\dynamic.py", line 72, in
_GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx,
pythoncom.IID_IDispatch)
com_error: (-2147221008, 'CoInitialize has not been called.', None,
None)

Is there an alternate initialization procedure that will work from
within a Thread?

Any help would be greatly appreciated.

Stephen

Adam Karpierz

unread,
Oct 31, 2002, 2:16:17 PM10/31/02
to
Uzytkownik "Stephen" <stephe...@paretopartners.com> napisal:

[...]


> from threading import Thread
>
> class foo:
> def run(self):
> try:
> import win32com.client

# You have to use pythoncom.CoInitialize and pythoncom.CoUninitialize eg.:

import pythoncom
pythoncom.CoInitialize()

> self.excel = win32com.client.Dispatch("Excel.Application")

pythoncom.CoUninitialize()

> self.excel.Visible = 1
> k = self.excel.Workbooks.Add()
> v = k.Worksheets(1)
> v.Cells(1,1).Value = str(self)
> except:
> import traceback
> traceback.print_exc()

Cheers

Adam Karpierz
karp...@zope.pl


Mark Hammond

unread,
Oct 31, 2002, 7:03:27 PM10/31/02
to
Adam Karpierz wrote:

> # You have to use pythoncom.CoInitialize and pythoncom.CoUninitialize eg.:

For all threads other than the main thread, correct.

>
> import pythoncom
> pythoncom.CoInitialize()
>
>
>> self.excel = win32com.client.Dispatch("Excel.Application")
>
>
> pythoncom.CoUninitialize()
>
>
>> self.excel.Visible = 1
>> k = self.excel.Workbooks.Add()
>> v = k.Worksheets(1)
>> v.Cells(1,1).Value = str(self)
>> except:
>> import traceback
>> traceback.print_exc()
>

This is wrong though. It should look more like:

import pythoncom
pythoncom.CoInitialize()
self.excel = win32com.client.Dispatch("Excel.Application")

self.excel.Visible = 1


k = self.excel.Workbooks.Add()
v = k.Worksheets(1)
v.Cells(1,1).Value = str(self)

# Remove all refs, then uninit.
self.excel = None
k = v = None
pythoncom.CoUninitialize()

ie, CoUninitialize should be the last thing done on a thread, and only
done after all references to objects created on that thread have been
destroyed.

Storing a thread-created COM object in your instance (ie, self.excel) is
a recipe for disaster, but I haven't time to go there now!

Mark.

dsavitsk

unread,
Nov 1, 2002, 1:26:42 AM11/1/02
to
"Stephen" <stephe...@paretopartners.com> wrote in message
news:24420294.02103...@posting.google.com...

> Hi -
>
> I am trying to get a threaded job server running that will thread
> scripts to manipulate various MS office apps.

running various MS office apps automatically can also be a recipe for
disaster. Word, in particular, can only have one instance going at a time
else it will do all the work into the same document. that is, if there are
2 scripts automating word they will both be automating the same document,
and likely crashing it.

to this end, i have been working on a spooler for word automation. you can
find the gist at http://ecpspooler.sourceforge.net. contact me if you are
interested.

-doug


Stephen

unread,
Nov 1, 2002, 3:12:51 PM11/1/02
to
Mark Hammond <mham...@skippinet.com.au> wrote in message news:<jxjw9.22695$jE1....@news-server.bigpond.net.au>...

Thanks, works like a charm! This last bit is a little ominous ...

>
> Storing a thread-created COM object in your instance (ie, self.excel) is
> a recipe for disaster, but I haven't time to go there now!
>
> Mark.

.. Is there a description or example in one of your books?

Stephen

Adam Karpierz

unread,
Nov 2, 2002, 4:44:44 AM11/2/02
to
Uzytkownik "Mark Hammond" <mham...@skippinet.com.au> napisal:

> This is wrong though. It should look more like:

Of course :)
Sorry for my mistake.

Adam Karpierz
karp...@zope.pl


0 new messages