com_error: (-2147221008, 'CoInitialize wurde nicht aufgerufe

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
lisan
User
Beiträge: 3
Registriert: Dienstag 14. März 2006, 11:22

Hi,
Ich bin python einsteiger und schreibe unter win ein office-zeugs konverter, dazu nutze ich eclipse + python (pydev).
Es geht bei meiner frage nicht um pythoncom spezifische eigenschaften, das problem steckt eher in den threads.

Dazu: Ich habe eine klasse word welche von officeapplication erbt welche wiederum von othread(Thread) erbt.

Die inits sehen wie folgt aus:

Code: Alles auswählen

class Word(office.Officeapplication):
    """A utility to make it easier to get at Ms Word."""
    def __init__( self, filename=None, printer=None ):
        ...
        self.event = WordEvent
        _Debug.debug( "init word instance" )
        super( Word, self ).__init__( 'Word.Application', self.event, filename, printer )
        ...

Code: Alles auswählen

class Officeapplication(OThread):
    '''
    class-constructor'''
    def __init__(self, name, event=None, filename=None, printer=None):
        super( Officeapplication, self ).__init__(None, None, name)
Die OThread klasse:

Code: Alles auswählen

# othread.py

from threading import Thread
import pythoncom

class OThread(Thread):
    def __init__(self, group=None, target=None, name=None):
        print "thread init called"
        Thread.__init__(self, group, target, name)
        print "mashall com for thread %s " % self.getName()
        pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
               
    def run(self):
        print "Implement me"
                      
    def __del__(self):
        pythoncom.CoUninitialize()
Die Klasse Officeapplication implementiert die methode run() wie folgt:

Code: Alles auswählen

def run(self):
        _Debug.debug("thread '%s' startet ..." % self.getName())
        
        before = []
        after = dict ([(f, None) for f in os.listdir (self.config['directory_in'])])
        added = [f for f in after if not f in before]
        for fn in added:
            if fn[-3:] in self.extensions:
                starttime = time.clock()
                self.printout(self.config['directory_in'] + "\\" + fn)
                while self.App.BackgroundPrintingStatus > 0:
                  time.sleep(0.1)
Die ausgabe des programmes sind:
creating a word com client object
init word instance
officeapplication inheritances
thread init called
mashall com for thread Word.Application
setting up eventhandler
thread 'Word.Application' startet ...
finalize
Word.Application
Exception in thread Word.Application:
Traceback (most recent call last):
File "C:\Python24\lib\threading.py", line 442, in __bootstrap
self.run()
File "e:\eclipse\workspace\Office2pdf\src\office.py", line 141, in run
self.printout(self.config['directory_in'] + "\\" + fn)
File "e:\eclipse\workspace\Office2pdf\src\word.py", line 126, in printout
for doc in self.App.Documents:
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 199, in __getattr__
return getattr(self._obj_, attr)
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 455, in __getattr__
return self._ApplyTypes_(*args)
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 446, in _ApplyTypes_
return self._get_good_object_(
com_error: (-2147221008, 'CoInitialize wurde nicht aufgerufen.', None, None)
Daraus schliesse ich, dass fuer den thread mit namen 'Word.application' nicht die CoInit methode aufgerufen worden ist.
Anhand der ausgaben sieht man aber, dass dies dennoch geschehen ist.

Was mache ich falsch ?

p.s. die ref. der CoInit methode http://aspn.activestate.com/ASPN/docs/A ... _meth.html
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lisan hat geschrieben:das problem steckt eher in den threads.
Hi lisan!

CoInitialize() sollte in deinem Fall genügen. CoInitialize() muss innerhalb des Threads aufgerufen werden. Beim Abarbeiten der Methode __init__() ist es noch kein eigenständiger Thread. Es wird erst ein eigenständiger Thread daraus, wenn die Methode run() ausgeführt wird. Du musst also CoInitialize() innerhalb von run() ausführen und kurz vor Beenden der "run"-Methode die Funktion CoUninitialize() ausführen.

Siehe: http://www.python-forum.de/viewtopic.php?p=32993#32993

Allerdings habe ich mir nicht die Mühe gemacht, deinen Code vollständig durchzulesen. Vielleicht liegt es ja auch an etwas anderem.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lisan
User
Beiträge: 3
Registriert: Dienstag 14. März 2006, 11:22

Der Gedanke kam mir auch aber nachdem ich dies dann Versucht hatte, ergab sich folgender Fehler:
creating a word com client object
init word instance
officeapplication inheritances
thread init called
mashall com for thread Word.Application
setting up eventhandler
thread 'Word.Application' startet ...
Word.Application wants to print
Exception in thread Word.Application:
Traceback (most recent call last):
File "C:\Python24\lib\threading.py", line 442, in __bootstrap
self.run()
File "e:\eclipse\workspace\Office2pdf\src\office.py", line 144, in run
self.printout(self.config['directory_in'] + "\\" + fn)
File "e:\eclipse\workspace\Office2pdf\src\word.py", line 94, in printout
for doc in self.App.Documents:
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 199, in __getattr__
return getattr(self._obj_, attr)
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 455, in __getattr__
return self._ApplyTypes_(*args)
File "C:\Python24\Lib\site-packages\win32com\client\__init__.py", line 446, in _ApplyTypes_
return self._get_good_object_(
com_error: (-2147417842, 'Eine Schnittstelle, die f\xfcr einen anderen Thread marshalled war, wurde von der Anwendung aufgerufen.', None, None)
Ausserdem muss ich destruktoren per hand aufrufen
wd.__del__() sonst werden diese nicht beruehrt.

Zum obigen Fehler: Ich vermute, dass die init vor dem run() aufgerufen werden und dort bereits lustige Dinge wie Dispatch etc. zu einem CoInit fuehren.
lisan
User
Beiträge: 3
Registriert: Dienstag 14. März 2006, 11:22

Hi,

ich konnte es mit deinen denkanstoss letztlich loesen:

Die Idee, dass hier etwas mit der reihenfolge (wann ist der thread im workflow ein thread) war zutreffend.

Ich musste auf der comschnittstelle aufsetzenden initialisierungen aus den __init__ methoden (konstruktoren) in den run() methode ziehen, da offensichtlich hier der thread erste ein thread ist und nicht wie angenommen nach aufruf des thread konstruktors.
Antworten