l...@sina.com schrieb: > Hi, > > there is a bug in comtypes.client.GetBestInterface, as this: > > ---- > ## the following code works fine > from comtypes.client import CreateObject > wscriptObj = CreateObject("Wscript.Shell",dynamic=True) > print(wscriptObj.CurrentDirectory) > wscriptObj.run("cmd.exe /c notepad.exe",0) > > # But, when drop the "dynamic=True", it will fail > from comtypes.client import CreateObject > wscriptObj = CreateObject("Wscript.Shell") > print(wscriptObj.CurrentDirectory) # Failed, AttributeError: > CurrentDirectory > wscriptObj.run("cmd.exe /c notepad.exe",0) > ---- > > Turns out that when progid="Wscript.Shell", in > comtypes.client.GetBestInterface, the pci.GetClassInfo() returned > TypeInfo of the default interface IWshShell3, not of the supposed > CoClass WshShell. GetBestInterface searched IWshShell3, find what it > implemented - IWshShell2, which has no property CurrentDirectory.
Yes, I see the problem. > > So I think here need an if stmt, such as "if (str(ta.guid) == punk.clsid): go > best interface", > or, try IDispatch.GetTypeInfo first. I do not really understand what you mean. But I have attached a patch for comtypes\client\__init__.py which should fix the problem. Index: __init__.py =================================================================== --- __init__.py (revision 564) +++ __init__.py (working copy) @@ -70,18 +70,28 @@ tinfo = pci.GetClassInfo() # TypeInfo for the CoClass # find the interface marked as default ta = tinfo.GetTypeAttr() - for index in range(ta.cImplTypes): - if tinfo.GetImplTypeFlags(index) == 1: - break - else: - if ta.cImplTypes != 1: - # Hm, should we use dynamic now? - raise TypeError("No default interface found") - # Only one interface implemented, use that (even if - # not marked as default). - index = 0 - href = tinfo.GetRefTypeOfImplType(index) - tinfo = tinfo.GetRefTypeInfo(href) + if ta.typekind in (3, 4): # TKIND_INTERFACE, TKIND_DISPATCH + # The tinfo that we got is an interface, we use this as + # the 'best interface' + pass + elif ta.typekind == 5: # TKIND_COCLASS + # The tinfo describes the coclass. We have to find out + # which interfaces this coclass implements and use the + # 'best' one. + for index in range(ta.cImplTypes): + if tinfo.GetImplTypeFlags(index) == 1: # IMPLTYPEFLAG_FDEFAULT + # This is the default interface + href = tinfo.GetRefTypeOfImplType(index) + tinfo = tinfo.GetRefTypeInfo(href) + break + else: + if ta.cImplTypes != 1: + # Hm, should we use dynamic now? + raise TypeError("No default interface found") + # Only one interface implemented, use that (even if + # not marked as default). + href = tinfo.GetRefTypeOfImplType(0) + tinfo = tinfo.GetRefTypeInfo(href) except comtypes.COMError: logger.debug("Does NOT implement IProvideClassInfo/IProvideClassInfo2") try: ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users