[python-win32] Accessing other interfaces of a Dispatch created COM object
Alec Munro
alecmunro at gmail.com
Wed Sep 17 21:54:30 CEST 2008
I've taken a look, and I can't say I had an "aha" moment, or anything
like that, but perhaps I have learned something important.
Setting up the COM object seems very straightforward:
Type t = Type.GetTypeFromCLSID("{e04f970b-53ce-420a-86f8-55374677703d}")
component = (basic.I1)Activator.CreateInstance(t)
component_2 = component as I2
The ID referenced there is the ID of the coclass in the COM DLL.
I've looked into where it gets "basic" from, and the important
property seems to be:
Identity: {35F40DBC-6CB3-4EEC-843B-57BB52CA2A93}\1.0\0\tlbimp
This ID is the CLSID of the Type Library in _basicUHI.tlb
I'll see if I can reproduce this exactly in Python, and if I get any
different results.
Alec
On Wed, Sep 17, 2008 at 4:28 PM, Alec Munro <alecmunro at gmail.com> wrote:
> If you hear a loud slapping sound, that's my hand and forehead. :)
>
> I just recalled that the third-party gives us a test application that
> uses the COM component. Including source.
>
> It's in C#, which is new to me, but looks pretty straightforward. I'm
> going to figure out how they do, then see if I can do the same thing
> through Python.
>
> Sorry I didn't think of this sooner.
>
> Alec
>
> On Wed, Sep 17, 2008 at 4:10 PM, Alec Munro <alecmunro at gmail.com> wrote:
>> I'm back.
>>
>> I've taken a crack at rewriting the DLL to export the methods I need
>> through IDispatch. Unfortunately, what I discovered (and I'm probably
>> describing this in the wrong way), is that the class is declared
>> ATL_NO_VTABLE, and as far as I can tell, the third-party app relies on
>> the interfaces being exported through IDispatch. This means that the
>> methods suggested here won't work:
>>
>> http://www.sellsbrothers.com/tools/multidisp/
>>
>> Or at least the first two.
>>
>> So I'm back to trying to figure out what might be going wrong in my
>> attempts to access the current implementation through Python.
>>
>> I wonder, is there any way to log IDispatch operations? If so, that
>> might tell me what the third-party operation was doing differently.
>>
>> I would be happy to hear any other suggestions.
>>
>> Thanks,
>>
>> Alec
>>
>> On Fri, Sep 12, 2008 at 2:28 PM, Alec Munro <alecmunro at gmail.com> wrote:
>>> (I just noticed my last two responses only went to Mark. They were
>>> intended for the Mailing List and Tim as well. Sorry for the
>>> oversight.)
>>>
>>> So I just ran some tests, fruitlessly. Here is what I did:
>>>
>>> - Removed all gen_py stuff
>>> - Set registry entries for both interfaces to point to the BASICUHI typelib.
>>> - Restarted
>>> - Use Make_py on BASICUHI typelib
>>>
>>> X: Same error
>>>
>>> - Use Make_py for other typelib
>>>
>>> X: Same error
>>>
>>> - Removed all gen_py stuff
>>> - Set registry entries for both interfaces to point to other typelib.
>>> - Restarted
>>> - Use Make_py for other typelib
>>>
>>> X: Same error
>>>
>>> - Use Make_py for BASICUHI typelib
>>>
>>> X: Same error
>>>
>>> What I'm wondering at this point is how I determine what Library it is
>>> that isn't registered. That might yield some clues, but right now I'm
>>> pretty much out of ideas, and toying seriously with the idea of
>>> rewriting the dll to allow it to export the interfaces I need through
>>> IDispatch.
>>>
>>> Thanks again for your time,
>>>
>>> Alec
>>>
>>>
>>> On Fri, Sep 12, 2008 at 1:49 PM, Alec Munro <alecmunro at gmail.com> wrote:
>>>> Hi Mark,
>>>>
>>>> Ok, with my first object, everything works as you demonstrated. With
>>>> my second object (the first one CastTo(,I2)), I get the "Library not
>>>> Registered" message when I call GetTypeInfo(), which I guess is what
>>>> you were expecting.
>>>>
>>>> As far as Tim's question goes, I looked up the ID for the BasicUHI
>>>> typelib in the registry, and the path there does indeed point to the
>>>> BasicUHI file.
>>>>
>>>> I've got some ideas for things I can test, for the moment, but if you
>>>> have any ideas or additional information, I would love to hear it.
>>>>
>>>> Thanks again!
>>>>
>>>> Alec
>>>>
>>>>
>>>> On Wed, Sep 10, 2008 at 10:35 PM, Alec Munro <alecmunro at gmail.com> wrote:
>>>>> Thanks Mark, Tim!
>>>>>
>>>>> Lots of excellent information there for someone as COM-confused as I am. :)
>>>>>
>>>>> I'll try out your suggestions tomorrow, to see what I find, but for
>>>>> now, here's a little more information on our situation.
>>>>>
>>>>> We use a third-party solution for testing our products. This solution
>>>>> requires us to create a COM dll with a class implementing specific
>>>>> interfaces (at least I1, any others are optional). The third party
>>>>> defines the interfaces, we just provide implementations for them. The
>>>>> third party provides us with their testing solution itself, as well as
>>>>> an SDK for developing the dll.
>>>>>
>>>>> In order to use the dll, we do register it manually using regsvr32.
>>>>> Any other registrations I would assume are performed by the installers
>>>>> from the third party.
>>>>>
>>>>> We've been using this for several years now (I only took over
>>>>> maintenance on the project 6 months ago), but this is the first time
>>>>> we are trying to access the dll ourselves, so it's fairly new
>>>>> territory.
>>>>>
>>>>> Hopefully that makes sense, thanks again,
>>>>>
>>>>> Alec
>>>>>
>>>>> On Wed, Sep 10, 2008 at 8:59 PM, Mark Hammond <mhammond at skippinet.com.au> wrote:
>>>>>> I'm still a little lost too, but:
>>>>>>
>>>>>>> * I maintain a dll that defines a class that implements I1 and I2. I
>>>>>>> use regsvr to register this dll.
>>>>>>> * I1 and I2 come from a third party, and in order for my dll to work
>>>>>>> properly, it has to implement them (actually I2 is optional).
>>>>>>> * I don't know how I1 and I2 are registered.
>>>>>>
>>>>>> I don't understand the above. If you maintain the class that implements I1
>>>>>> and I2 how can:
>>>>>>
>>>>>> * they come from a 3rd party - either you maintain them, or they do?
>>>>>> * Surely you know how they are registered?
>>>>>>
>>>>>>
>>>>>>> I do know that if I use
>>>>>>> the COM browser, I can go to Registered Type Libraries, find one with
>>>>>>> the typelibname that is associated with my CastTo created objects,
>>>>>>> which has "Type Library" underneath it, and underneath that are
>>>>>>> entries for I1, I2, several related interfaces, and a variety of
>>>>>>> coclasses. Like this:
>>>>>>> - TypeLibName 1.0 TypeLibrary
>>>>>>> -- IID: {00..00}
>>>>>>> -- Type Library
>>>>>>> --- I1 - Dispatch
>>>>>>> --- I2 - Dispatch
>>>>>>> --- IX - Dispatch
>>>>>>> --- CX - CoClass
>>>>>>>
>>>>>>> I've just spent some time hunting through the registry to determine
>>>>>>> the differences between I1 and I2.
>>>>>>
>>>>>> What I'm guessing is that the GetTypeInfo() and GetTypeLib() calls for the
>>>>>> other dispatch object are failing. Below is how we expect things to work,
>>>>>> demonstratrated using for Internet Explorer:
>>>>>>
>>>>>>>>> from win32com.client import Dispatch
>>>>>>>>> d=Dispatch("InternetExplorer.Application")
>>>>>>>>> d=d._oleobj_
>>>>>>>>> d.GetTypeInfoCount()
>>>>>> 1
>>>>>>>>> d.GetTypeInfo(0)
>>>>>> <PyITypeInfo at 0x00D1B038 with obj at 0x0025285C>
>>>>>>>>> i=d.GetTypeInfo(0)
>>>>>>>>> tlb, index=i.GetContainingTypeLib()
>>>>>>>>> tlb.GetLibAttr()
>>>>>> (IID('{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}'), 0, 1, 1, 1, 8)
>>>>>>>>>
>>>>>>
>>>>>> Which is the GUID, version, locale etc information (a TLIBATTR structure)
>>>>>> for the typelib, and you will find this in the registry. It sounds like
>>>>>> this works for one of your objects and fails for the other (well - "fails"
>>>>>> might mean that the call works, but returns a GID and version info for a
>>>>>> typelib that isn't registered - ie, attempting to load that typelib would
>>>>>> fail.) ie, you would also need the following to work:
>>>>>>
>>>>>>>>> guid, lcid, syskind, majver, minver, flags = tlb.GetLibAttr()
>>>>>>>>> import pythoncom
>>>>>>>>> pythoncom.LoadRegTypeLib(guid, majver, minver, lcid)
>>>>>> <PyITypeLib at 0x00D1B038 with obj at 0x00254530>
>>>>>>>>> _.GetDocumentation(1)
>>>>>> (u'DWebBrowserEvents', u'Web Browser Control Events (old)', 0, None)
>>>>>>>>>
>>>>>>
>>>>>> Hope this helps,
>>>>>>
>>>>>> Mark
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
More information about the python-win32
mailing list