Try to QueryInterface a COM pointer to the 'most useful' interface. Get type information for the provided object, either via IDispatch.GetTypeInfo(), or via IProvideClassInfo.GetClassInfo(). Generate a wrapper module for the typelib, and QI for the interface found.
(punk: Any)
| 20 | |
| 21 | |
| 22 | def GetBestInterface(punk: Any) -> Any: |
| 23 | """Try to QueryInterface a COM pointer to the 'most useful' |
| 24 | interface. |
| 25 | |
| 26 | Get type information for the provided object, either via |
| 27 | IDispatch.GetTypeInfo(), or via IProvideClassInfo.GetClassInfo(). |
| 28 | Generate a wrapper module for the typelib, and QI for the |
| 29 | interface found. |
| 30 | """ |
| 31 | if not punk: # NULL COM pointer |
| 32 | return punk # or should we return None? |
| 33 | # find the typelib and the interface name |
| 34 | logger.debug("GetBestInterface(%s)", punk) |
| 35 | try: |
| 36 | try: |
| 37 | pci = punk.QueryInterface(typeinfo.IProvideClassInfo) |
| 38 | logger.debug("Does implement IProvideClassInfo") |
| 39 | except COMError: |
| 40 | # Some COM objects support IProvideClassInfo2, but not IProvideClassInfo. |
| 41 | # These objects are broken, but we support them anyway. |
| 42 | logger.debug( |
| 43 | "Does NOT implement IProvideClassInfo, trying IProvideClassInfo2" |
| 44 | ) |
| 45 | pci = punk.QueryInterface(typeinfo.IProvideClassInfo2) |
| 46 | logger.debug("Does implement IProvideClassInfo2") |
| 47 | tinfo = pci.GetClassInfo() # TypeInfo for the CoClass |
| 48 | # find the interface marked as default |
| 49 | ta = tinfo.GetTypeAttr() |
| 50 | for index in range(ta.cImplTypes): |
| 51 | if tinfo.GetImplTypeFlags(index) == 1: |
| 52 | break |
| 53 | else: |
| 54 | if ta.cImplTypes != 1: |
| 55 | # Hm, should we use dynamic now? |
| 56 | raise TypeError("No default interface found") |
| 57 | # Only one interface implemented, use that (even if |
| 58 | # not marked as default). |
| 59 | index = 0 |
| 60 | href = tinfo.GetRefTypeOfImplType(index) |
| 61 | tinfo = tinfo.GetRefTypeInfo(href) |
| 62 | except COMError: |
| 63 | logger.debug("Does NOT implement IProvideClassInfo/IProvideClassInfo2") |
| 64 | try: |
| 65 | pdisp = punk.QueryInterface(automation.IDispatch) |
| 66 | except COMError: |
| 67 | logger.debug("No Dispatch interface: %s", punk) |
| 68 | return punk |
| 69 | try: |
| 70 | tinfo = pdisp.GetTypeInfo(0) |
| 71 | except COMError: |
| 72 | pdisp = comtypes.client.dynamic.Dispatch(pdisp) |
| 73 | logger.debug("IDispatch.GetTypeInfo(0) failed: %s" % pdisp) |
| 74 | return pdisp |
| 75 | typeattr = tinfo.GetTypeAttr() |
| 76 | logger.debug("Default interface is %s", typeattr.guid) |
| 77 | try: |
| 78 | punk.QueryInterface(IUnknown, typeattr.guid) |
| 79 | except COMError: |
no test coverage detected
searching dependent graphs…