[python-win32] Cannot get COM early bound

Stephen George steve_geo at optusnet.com.au
Thu May 17 03:32:11 CEST 2007


Greetings,

I have been a COM expert for all of two days ;-)

I did get a Type Mismatch error on an argument, .. the more I dug and 
researched this error, the more I found out and now have a question 
about early binding.

I am trying to get access to two COM objects/interfaces <=(don't know 
what word to use here, so bear with me if I get it wrong)

The COM objects I'm interested in are ClearCase Automation Library (CAL) 
& ClearQuestOLEServer

I ran makepy on both of these.
selected info from each of the generated files is
===============================
# From type library 'ccauto.dll'
# On Wed May 16 16:38:12 2007
"""ClearCase Automation Library 6.0"""
makepy_version = '0.4.95'
python_version = 0x20500f0
 ::         ::
# This CoClass is known by the name 'ClearCase.Application.1'
class Application(CoClassBaseClass): # A CoClass
===============================
# From type library 'cqole.dll'
# On Wed May 16 16:37:15 2007
""""""
makepy_version = '0.4.95'
python_version = 0x20500f0
 ::         ::
# This CoClass is known by the name 'CLEARQUEST.SESSION'
class Session(CoClassBaseClass): # A CoClass
===============================

Chapter 12 of Marks book, indicates case sensitivity can be a problem 
for late bound
Also VARIANT translations may not work so well under late bound.

I wanted to use early bound to ensure my VARIANTS are correct. But I 
cannot get the
CLEARQUEST.SESSION early bound. I successfully got ClearCase.Application 
early bound

The output of my program indicates that the ClearCase.Application object 
was early bound, but I
could do nothing to get CLEARQUEST.SESSION early bound

==========My Program=============
import win32com.client as w32c
import pythoncom
from win32com.client import constants
try:
    cc = w32c.Dispatch(r"ClearCase.Application")
    print "CC:",cc
except TypeError, detail:
    print "ClearCase exception: TypeError", detail
print '--------------------------------------------------------'
#---------------ClearQuest ----------------  
try:
    from win32com.client import gencache
    gencache.EnsureModule('{B805FDF6-BEA8-11D1-B36D-00A0C9851B52}', 0, 1, 0)
    cq_session = w32c.Dispatch(r"CLEARQUEST.SESSION")
#    cq_session = w32c.Dispatch(r"Clearquest.Session")
#    cq_session = w32c.Dispatch(r"ClearQuest.Session")
#    cq_session = w32c.Dispatch(r"clearquest.session")
#    cq_session = w32c.Dispatch('{B805FDF6-BEA8-11D1-B36D-00A0C9851B52}')
    print "CQ:",cq_session
    cq_session.UserLogon( 'sgeorge', 'sgeorge', "OSI", "" );
except pythoncom.com_error ,(hr, msg, exc, arg):
    print 'HRESULT\t%d: %s' % (hr, msg)
    if exc:
        wcode, source, text, helpFile, helpId, scode = exc
        print 'The source of the error is', source
        print 'The error message is', text
        print "More info can be found in %s (id=%d)" % (helpFile, helpId)

========= Output ===============================
D:\tempSVNPyFiles\clearcase>testcom.py
CC: <win32com.gen_py.ClearCase Automation Library 6.0.IClearCase 
instance at 0x16076152>
--------------------------------------------------------
CQ: <COMObject CLEARQUEST.SESSION>
HRESULT -2147352571: Type mismatch.
=================================================

According to Chp. 12, the  'win32com.gen_py' bit indicates early binding 
and 'COMObject ' indicates late binding

To ensure early binding as per the book , I force the makepy process 
from the source using info from running makepy.py -i

D:\tempSVNPyFiles\clearcase>c:\python24\Lib\site-packages\win32com\client\makepy.py 
-i
ClearQuestOleServer
 {B805FDF6-BEA8-11D1-B36D-00A0C9851B52}, lcid=0, major=1, minor=0
 >>> # Use these commands in Python code to auto generate .py support
 >>> from win32com.client import gencache
 >>> gencache.EnsureModule('{B805FDF6-BEA8-11D1-B36D-00A0C9851B52}', 0, 
1, 0)

I also experimented with the case of the object name CLEARQUEST.SESSION, 
as can been seen in the source. All resulted in late binding.

The final test is passing in the CLSID  (hope this is the right format)
    cq_session = w32c.Dispatch('{B805FDF6-BEA8-11D1-B36D-00A0C9851B52}')
Which resulted in

D:\tempSVNPyFiles\clearcase>testcom.py
CC: <win32com.gen_py.ClearCase Automation Library 6.0.IClearCase 
instance at 0x16083224>
--------------------------------------------------------
HRESULT -2147221164: Class not registered

Making me wonder whats going on?

I'm unsure were to go from here.

======================
Possibly separate but related, I have notice something funny.
I deleted the cache of generated py files by deleting the directory 
C:\Python25\Lib\site-packages\win32com\gen_py  (not 
Python\win32com\gen_py as the book suggests)

And re-run the application, and ClearCase.Application was still early 
bound (although it should not be as I was not forcing it)
CC: <win32com.gen_py.ClearCase Automation Library 6.0.IClearCase 
instance at 0x16076152>

I had noticed on some occasions (not all) when I run makepy.py (from 
command line), it sticks stuff into a temp directory instead of 
win32com\gen.py ???
D:\tempSVNPyFiles\clearcase>
D:\tempSVNPyFiles\clearcase>c:\python25\Lib\site-packages\win32com\client\makepy.py
Generating to 
C:\DOCUME~1\SGEORG~1.OSI\LOCALS~1\Temp\gen_py\2.5\B22C7EFA-5A5E-11D3-B1CD-00C04F8ECE2Fx0x6x0.py
Building definitions from type library...
Generating...
Importing module

If I then run makepy from PythonWin It correctly puts things into 
\win32com\gen_py
Subsequent runs from the command line then correctly put into 
win32com\gen_py

So out of curiosity after deleting gen_py from the python directory, 
checking that the app was still early bound, I went to the temp 
directory and deleted the gen_py directory from there. finally ClearCase 
was late bound.
CC: <COMObject ClearCase.Application>

Why would my application be picking up the generated com interface file 
from a temp directory??

I could not work out the trigger for getting makepy.py into this mode. I 
suspected running with -i argument or running makepy from python24 which 
I also have co-installed, but I couldn't reproduce on demand.

However once I re-assured myself that the ONLY  gen_py directory on my 
hard disk was in C:\Python25\Lib\site-packages\win32com\ and the two COM 
interface I was interested in had both been generated into this 
directory, I still had one late bound and one early bound.

A further test showed that if no gen_py directory exists on my hard 
disk, both under python24 and python25  the following code
 >> from win32com.client import gencache
 >> gencache.EnsureModule('{B805FDF6-BEA8-11D1-B36D-00A0C9851B52}', 0, 1, 0)

created the gen_py directory in the temp directory - Maybe this is the 
correct behavior for users without permissions?

After this a subsequent run of make_py from the command line put the 
resultant gen_py files also into the gen_py directory of the temp 
directory instead of under python?

I'm confused if I'm observing correct behavior?, and as to why I cannot 
get CLEARQUEST.SESSION early bound.

Any comments appreciated
Thanks
Steve


More information about the Python-win32 mailing list