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

Python and win32com question

0 views
Skip to first unread message

John Smith

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
I have a COM server with the following interface structure:

IMain
|
---IFirst
| |
| --- Method1()
| --- Method2()
|
---ISecond
|
--- Method1()
--- Method2()

The only way to get at the IFirst and ISecond interfaces is to access
the IMain interface and then use QueryInterface(). I have a C++ program
where I can do this:

<<
HRESULT RC = S_OK;
IMain * pMain = NULL;
IFirst * pFirst = NULL;

RC = CoCreateInstance(
CLSID_Main,
NULL,
CLSCTX_ALL,
IID_IMain,
(void**) &pMain );

if ( SUCCEEDED( RC ) )
{
RC = pMain->QueryInterface(
IID_IFirst,
(void**) &pFirst );

if ( SUCCEEDED( RC ) )
{
RC = pFirst->Method1();
}
}
>>

I would like to be able to do the following on python:

<<
import win32com, pythoncom

CLSID_Main = pythoncom.MakeIID('{340B352F-216C-11D2-997F-0060B0A18829}')

IID_IMain = pythoncom.MakeIID('{340B352E-216C-11D2-997F-0060B0A18829}')
IID_IFirst = pythoncom.MakeIID('{438082C1-2861-11D2-A717-0060B0B41584}')

objMain = pythoncom.CoCreateInstance(
CLSID_Main,
None,
pythoncom.CLSCTX_ALL,
IID_IMain )

objFirst = objMain.QueryInterface( IID_IFirst )

objFirst.Method1()
>>

But I get the error: "TypeError: There is no interface object registered
that supports this IID" on the CoCreateInstance line. I have double
checked the IIDs I'm using and they are what ia in the IDL for the COM
server. If I change the IID_Main to pythoncom.IID_IDispatch or
pythoncom.IID_IUnknown this line works, but the QueryInterface line
fails with the error: "TypeError: There is no interface object
registered that supports this IID". Am I trying to do something that is
not supported?

Thanks!

Jim Kyser
Kys...@aol.com


Thomas Heller

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to

John Smith wrote in message <36FBE484...@company.com>...

>I have a COM server with the following interface structure:
>
>IMain
> |
> ---IFirst
> | |
> | --- Method1()
> | --- Method2()
> |
> ---ISecond
> |
> --- Method1()
> --- Method2()
>

[...]


>
>But I get the error: "TypeError: There is no interface object registered
>that supports this IID" on the CoCreateInstance line. I have double
>checked the IIDs I'm using and they are what ia in the IDL for the COM
>server. If I change the IID_Main to pythoncom.IID_IDispatch or
>pythoncom.IID_IUnknown this line works, but the QueryInterface line
>fails with the error: "TypeError: There is no interface object
>registered that supports this IID". Am I trying to do something that is
>not supported?

It seems you are doing something unsupported: look at the error message.
Python (or pythoncom) does not know anything about your IFirst
or ISecond interface.
I'm not sure, however, how you would proceed...,
also still playing with win32com.

Thomas Heller


Mark Hammond

unread,
Mar 27, 1999, 3:00:00 AM3/27/99
to
Thomas Heller wrote in message <7dgqrn$a18$1...@mars.ms.tlk.com>...

>
>John Smith wrote in message <36FBE484...@company.com>...
>>I have a COM server with the following interface structure:
>>
>>But I get the error: "TypeError: There is no interface object registered
>>that supports this IID" on the CoCreateInstance line. I have double
>>checked the IIDs I'm using and they are what ia in the IDL for the COM
>>server. If I change the IID_Main to pythoncom.IID_IDispatch or
>>pythoncom.IID_IUnknown this line works, but the QueryInterface line
>>fails with the error: "TypeError: There is no interface object
>>registered that supports this IID". Am I trying to do something that is
>>not supported?
>
>It seems you are doing something unsupported: look at the error message.
>Python (or pythoncom) does not know anything about your IFirst
>or ISecond interface.
>I'm not sure, however, how you would proceed...,
>also still playing with win32com.

That is correct. Pythoncom can not handle arbitrary vtable based
interfaces.

Does the object support a "dual interface" - ie, have you tried querying the
object for IDispatch? If so, it should work fine from Python...

The only decent way to proceed is to write a Pythoncom extension DLL - which
is exactly what the mapi and axscript extensions are. Fortunately, you can
use SWIG (mail me for details), or the win32com.makepw package (again, you
will almost certainly need to mail me for details!)

Mark.

Toby Dickenson

unread,
Mar 28, 1999, 3:00:00 AM3/28/99
to
"Mark Hammond" <MHam...@skippinet.com.au> wrote:

>Thomas Heller wrote in message <7dgqrn$a18$1...@mars.ms.tlk.com>...
>>
>>John Smith wrote in message <36FBE484...@company.com>...
>>>I have a COM server with the following interface structure:
>>>
>>>But I get the error: "TypeError: There is no interface object registered
>>>that supports this IID" on the CoCreateInstance line. I have double
>>>checked the IIDs I'm using and they are what ia in the IDL for the COM
>>>server. If I change the IID_Main to pythoncom.IID_IDispatch or
>>>pythoncom.IID_IUnknown this line works, but the QueryInterface line
>>>fails with the error: "TypeError: There is no interface object
>>>registered that supports this IID". Am I trying to do something that is
>>>not supported?
>>
>>It seems you are doing something unsupported: look at the error message.
>>Python (or pythoncom) does not know anything about your IFirst
>>or ISecond interface.
>>I'm not sure, however, how you would proceed...,
>>also still playing with win32com.
>
>That is correct. Pythoncom can not handle arbitrary vtable based
>interfaces.
>
>Does the object support a "dual interface" - ie, have you tried querying the
>object for IDispatch? If so, it should work fine from Python...

This touches on something I have been looking at recently, which may answer your
problem...

What if one object has two dispinterfaces (or dual interfaces). Python works
naturally with the one that can be obtained by querying for IID_IDispatch, but
using the other seems to require a little more work. The following pythoncom
voodoo does the job:

def qi(object,iid):
# Query for given iid, but use the IDispatch wrapper. The given iid
# must correspond to a dual interface or dispinterface
dispatch=object._oleobj_.QueryInterface(iid,pythoncom.IID_IDispatch)
# Create the best dispatch object we can, using makepy version if possible
return win32com.client.Dispatch(dispatch,resultCLSID=iid)


This enables code like:

def test():
mod=gencache.EnsureModule('{439F43A0-E214-11D2-802D-D8DC3F41A314}',0,1,0)
first_dual_interface=mod.duali()
other_dual_interface=qi(first_dual_interface,mod.Iduali2.CLSID)


You can make this nicer (and, coincidentally, closer to VB) by manually hacking
the makepy generated code (from build 123), changing the DispatchBaseClass
constructor to:

def __init__(self, oobj=None):
if oobj is None:
oobj = pythoncom.new(self.CLSID)
elif type(self) == type(oobj): # An instance; must be a valid COM instance
oobj = oobj._oleobj_.QueryInterface(self.CLSID,pythoncom.IID_IDispatch)

(note - indentation changed to prevent line wrap)

This allows code such as:

def test():
mod=gencache.EnsureModule('{439F43A0-E214-11D2-802D-D8DC3F41A314}',0,1,0)
first_dual_interface=mod.duali()
other_dual_interface=mod.Iduali2(first_dual_interface)


Mark, any thoughts on adding this to the standard makepy?

Mark Hammond

unread,
Mar 29, 1999, 3:00:00 AM3/29/99
to
Toby Dickenson wrote in message <36fe8305...@news.freeserve.net>...
...

>Mark, any thoughts on adding this to the standard makepy?


<sigh> I answered this by email before I realised it had also been posted.

My answer was "I cant see why this object needs this special behaviour -
please enlighten me"

Mark.

0 new messages