0001 """A utility for browsing COM objects. 0002 0003 Usage: 0004 0005 Command Prompt 0006 0007 Use the command *"python.exe catbrowse.py"*. This will display 0008 display a fairly small, modal dialog. 0009 0010 Pythonwin 0011 0012 Use the "Run Script" menu item, and this will create the browser in an 0013 MDI window. This window can be fully resized. 0014 0015 Details 0016 0017 This module allows browsing of registered Type Libraries, COM categories, 0018 and running COM objects. The display is similar to the Pythonwin object 0019 browser, and displays the objects in a hierarchical window. 0020 0021 Note that this module requires the win32ui (ie, Pythonwin) diestribution to 0022 work. 0023 0024 """ 0025 import win32con 0026 import win32api, win32ui 0027 import string, sys 0028 import pythoncom 0029 from win32com.client import util 0030 from pywin.tools import browser 0031 0032 class HLIRoot(browser.HLIPythonObject): 0033 def __init__(self, title): 0034 self.name = title 0035 def GetSubList(self): 0036 return [HLIHeadingCategory(), HLI_IEnumMoniker(pythoncom.GetRunningObjectTable().EnumRunning(), "Running Objects"), HLIHeadingRegisterdTypeLibs()] 0037 def __cmp__(self, other): 0038 return cmp(self.name, other.name) 0039 0040 class HLICOM(browser.HLIPythonObject): 0041 def GetText(self): 0042 return self.name 0043 def CalculateIsExpandable(self): 0044 return 1 0045 0046 class HLICLSID(HLICOM): 0047 def __init__(self, myobject, name=None ): 0048 if type(myobject)==type(''): 0049 myobject = pythoncom.MakeIID(myobject) 0050 if name is None: 0051 try: 0052 name = pythoncom.ProgIDFromCLSID(myobject) 0053 except pythoncom.com_error: 0054 name = str(myobject) 0055 name = "IID: " + name 0056 HLICOM.__init__(self, myobject, name) 0057 def CalculateIsExpandable(self): 0058 return 0 0059 def GetSubList(self): 0060 return [] 0061 0062 class HLI_Interface(HLICOM): 0063 pass 0064 0065 class HLI_Enum(HLI_Interface): 0066 def GetBitmapColumn(self): 0067 return 0 # Always a folder. 0068 def CalculateIsExpandable(self): 0069 if self.myobject is not None: 0070 rc = len(self.myobject.Next(1))>0 0071 self.myobject.Reset() 0072 else: 0073 rc = 0 0074 return rc 0075 pass 0076 0077 class HLI_IEnumMoniker(HLI_Enum): 0078 def GetSubList(self): 0079 ctx = pythoncom.CreateBindCtx() 0080 ret = [] 0081 for mon in util.Enumerator(self.myobject): 0082 ret.append(HLI_IMoniker(mon, mon.GetDisplayName(ctx, None))) 0083 return ret 0084 0085 class HLI_IMoniker(HLI_Interface): 0086 def GetSubList(self): 0087 ret = [] 0088 ret.append(browser.MakeHLI(self.myobject.Hash(), "Hash Value")) 0089 subenum = self.myobject.Enum(1) 0090 ret.append(HLI_IEnumMoniker(subenum, "Sub Monikers")) 0091 return ret 0092 0093 class HLIHeadingCategory(HLICOM): 0094 "A tree heading for registered categories" 0095 def GetText(self): 0096 return "Registered Categories" 0097 def GetSubList(self): 0098 catinf=pythoncom.CoCreateInstance(pythoncom.CLSID_StdComponentCategoriesMgr,None,pythoncom.CLSCTX_INPROC,pythoncom.IID_ICatInformation) 0099 enum=util.Enumerator(catinf.EnumCategories()) 0100 ret = [] 0101 try: 0102 for catid, lcid, desc in enum: 0103 ret.append(HLICategory((catid, lcid, desc))) 0104 except pythoncom.com_error: 0105 # Registered categories occasionally seem to give spurious errors. 0106 pass # Use what we already have. 0107 return ret 0108 0109 class HLICategory(HLICOM): 0110 "An actual Registered Category" 0111 def GetText(self): 0112 desc = self.myobject[2] 0113 if not desc: desc = "(unnamed category)" 0114 return desc 0115 def GetSubList(self): 0116 win32ui.DoWaitCursor(1) 0117 catid, lcid, desc = self.myobject 0118 catinf=pythoncom.CoCreateInstance(pythoncom.CLSID_StdComponentCategoriesMgr,None,pythoncom.CLSCTX_INPROC,pythoncom.IID_ICatInformation) 0119 ret = [] 0120 for clsid in util.Enumerator(catinf.EnumClassesOfCategories((catid,),())): 0121 ret.append(HLICLSID(clsid)) 0122 win32ui.DoWaitCursor(0) 0123 0124 return ret 0125 0126 class HLIHelpFile(HLICOM): 0127 def CalculateIsExpandable(self): 0128 return 0 0129 def GetText(self): 0130 import os 0131 fname, ctx = self.myobject 0132 base = os.path.split(fname)[1] 0133 return "Help reference in %s" %( base) 0134 0135 def TakeDefaultAction(self): 0136 fname, ctx = self.myobject 0137 if ctx: 0138 cmd = win32con.HELP_CONTEXT 0139 else: 0140 cmd = win32con.HELP_FINDER 0141 win32api.WinHelp(win32ui.GetMainFrame().GetSafeHwnd(), fname, cmd, ctx) 0142 def GetBitmapColumn(self): 0143 return 6 0144 0145 class HLIRegisteredTypeLibrary(HLICOM): 0146 def GetSubList(self): 0147 import os 0148 clsidstr, versionStr = self.myobject 0149 collected = [] 0150 helpPath = "" 0151 key = win32api.RegOpenKey(win32con.HKEY_CLASSES_ROOT, "TypeLib\\%s\\%s" % (clsidstr, versionStr)) 0152 win32ui.DoWaitCursor(1) 0153 try: 0154 num = 0 0155 while 1: 0156 try: 0157 subKey = win32api.RegEnumKey(key, num) 0158 except win32api.error: 0159 break 0160 hSubKey = win32api.RegOpenKey(key, subKey) 0161 try: 0162 value, typ = win32api.RegQueryValueEx(hSubKey, None) 0163 if typ == win32con.REG_EXPAND_SZ: 0164 value = win32api.ExpandEnvironmentStrings(value) 0165 except win32api.error: 0166 value = "" 0167 if subKey=="HELPDIR": 0168 helpPath = value 0169 elif subKey=="Flags": 0170 flags = value 0171 else: 0172 try: 0173 lcid = string.atof(subKey) 0174 lcidkey = win32api.RegOpenKey(key, subKey) 0175 # Enumerate the platforms 0176 lcidnum = 0 0177 while 1: 0178 try: 0179 platform = win32api.RegEnumKey(lcidkey, lcidnum) 0180 except win32api.error: 0181 break 0182 try: 0183 hplatform = win32api.RegOpenKey(lcidkey, platform) 0184 fname, typ = win32api.RegQueryValueEx(hplatform, None) 0185 if typ == win32con.REG_EXPAND_SZ: 0186 fname = win32api.ExpandEnvironmentStrings(fname) 0187 except win32api.error: 0188 fname = "" 0189 collected.append((lcid, platform, fname)) 0190 lcidnum = lcidnum + 1 0191 win32api.RegCloseKey(lcidkey) 0192 except ValueError: 0193 pass 0194 num = num + 1 0195 finally: 0196 win32ui.DoWaitCursor(0) 0197 win32api.RegCloseKey(key) 0198 # Now, loop over my collected objects, adding a TypeLib and a HelpFile 0199 ret = [] 0200 # if helpPath: ret.append(browser.MakeHLI(helpPath, "Help Path")) 0201 ret.append(HLICLSID(clsidstr)) 0202 for lcid, platform, fname in collected: 0203 extraDescs = [] 0204 if platform!="win32": 0205 extraDescs.append(platform) 0206 if lcid: 0207 extraDescs.append("locale=%s"%lcid) 0208 extraDesc = "" 0209 if extraDescs: extraDesc = " (%s)" % string.join(extraDescs, ", ") 0210 ret.append(HLITypeLib(fname, "Type Library" + extraDesc)) 0211 ret.sort() 0212 return ret 0213 0214 class HLITypeLibEntry(HLICOM): 0215 def GetText(self): 0216 tlb, index = self.myobject 0217 name, doc, ctx, helpFile = tlb.GetDocumentation(index) 0218 try: 0219 typedesc = HLITypeKinds[tlb.GetTypeInfoType(index)][1] 0220 except KeyError: 0221 typedesc = "Unknown!" 0222 return name + " - " + typedesc 0223 def GetSubList(self): 0224 tlb, index = self.myobject 0225 name, doc, ctx, helpFile = tlb.GetDocumentation(index) 0226 ret = [] 0227 if doc: ret.append(browser.HLIDocString(doc, "Doc")) 0228 if helpFile: ret.append(HLIHelpFile( (helpFile, ctx) )) 0229 return ret 0230 0231 class HLICoClass(HLITypeLibEntry): 0232 def GetSubList(self): 0233 ret = HLITypeLibEntry.GetSubList(self) 0234 tlb, index = self.myobject 0235 typeinfo = tlb.GetTypeInfo(index) 0236 attr = typeinfo.GetTypeAttr() 0237 for j in range(attr[8]): 0238 flags = typeinfo.GetImplTypeFlags(j) 0239 refType = typeinfo.GetRefTypeInfo(typeinfo.GetRefTypeOfImplType(j)) 0240 refAttr = refType.GetTypeAttr() 0241 ret.append(browser.MakeHLI(refAttr[0], "Name=%s, Flags = %d" % (refAttr[0], flags))) 0242 return ret 0243 0244 0245 class HLITypeLibMethod(HLITypeLibEntry): 0246 def __init__(self, ob, name = None): 0247 self.entry_type = "Method" 0248 HLITypeLibEntry.__init__(self, ob, name) 0249 def GetSubList(self): 0250 ret = HLITypeLibEntry.GetSubList(self) 0251 tlb, index = self.myobject 0252 typeinfo = tlb.GetTypeInfo(index) 0253 attr = typeinfo.GetTypeAttr() 0254 for i in range(attr[7]): 0255 ret.append(HLITypeLibProperty((typeinfo, i))) 0256 for i in range(attr[6]): 0257 ret.append(HLITypeLibFunction((typeinfo, i))) 0258 return ret 0259 0260 class HLITypeLibEnum(HLITypeLibEntry): 0261 def __init__(self, myitem): 0262 typelib, index = myitem 0263 typeinfo = typelib.GetTypeInfo(index) 0264 self.id = typeinfo.GetVarDesc(index)[0] 0265 name = typeinfo.GetNames(self.id)[0] 0266 HLITypeLibEntry.__init__(self, myitem, name) 0267 def GetText(self): 0268 return self.name + " - Enum/Module" 0269 def GetSubList(self): 0270 ret = [] 0271 typelib, index = self.myobject 0272 typeinfo = typelib.GetTypeInfo(index) 0273 attr = typeinfo.GetTypeAttr() 0274 for j in range(attr[7]): 0275 vdesc = typeinfo.GetVarDesc(j) 0276 name = typeinfo.GetNames(vdesc[0])[0] 0277 ret.append(browser.MakeHLI(vdesc[1], name)) 0278 return ret 0279 0280 class HLITypeLibProperty(HLICOM): 0281 def __init__(self, myitem): 0282 typeinfo, index = myitem 0283 self.id = typeinfo.GetVarDesc(index)[0] 0284 name = typeinfo.GetNames(self.id)[0] 0285 HLICOM.__init__(self, myitem, name) 0286 def GetText(self): 0287 return self.name + " - Property" 0288 def GetSubList(self): 0289 ret = [] 0290 typeinfo, index = self.myobject 0291 names = typeinfo.GetNames(self.id) 0292 if len(names)>1: 0293 ret.append(browser.MakeHLI(names[1:], "Named Params")) 0294 vd = typeinfo.GetVarDesc(index) 0295 ret.append(browser.MakeHLI(self.id, "Dispatch ID")) 0296 ret.append(browser.MakeHLI(vd[1], "Value")) 0297 ret.append(browser.MakeHLI(vd[2], "Elem Desc")) 0298 ret.append(browser.MakeHLI(vd[3], "Var Flags")) 0299 ret.append(browser.MakeHLI(vd[4], "Var Kind")) 0300 return ret 0301 0302 class HLITypeLibFunction(HLICOM): 0303 funckinds = {pythoncom.FUNC_VIRTUAL : "Virtual", 0304 pythoncom.FUNC_PUREVIRTUAL : "Pure Virtual", 0305 pythoncom.FUNC_STATIC : "Static", 0306 pythoncom.FUNC_DISPATCH : "Dispatch", 0307 } 0308 invokekinds = {pythoncom.INVOKE_FUNC: "Function", 0309 pythoncom.INVOKE_PROPERTYGET : "Property Get", 0310 pythoncom.INVOKE_PROPERTYPUT : "Property Put", 0311 pythoncom.INVOKE_PROPERTYPUTREF : "Property Put by reference", 0312 } 0313 funcflags = [(pythoncom.FUNCFLAG_FRESTRICTED, "Restricted"), 0314 (pythoncom.FUNCFLAG_FSOURCE, "Source"), 0315 (pythoncom.FUNCFLAG_FBINDABLE, "Bindable"), 0316 (pythoncom.FUNCFLAG_FREQUESTEDIT, "Request Edit"), 0317 (pythoncom.FUNCFLAG_FDISPLAYBIND, "Display Bind"), 0318 (pythoncom.FUNCFLAG_FDEFAULTBIND, "Default Bind"), 0319 (pythoncom.FUNCFLAG_FHIDDEN, "Hidden"), 0320 (pythoncom.FUNCFLAG_FUSESGETLASTERROR, "Uses GetLastError"), 0321 ] 0322 0323 vartypes = {pythoncom.VT_EMPTY: "Empty", 0324 pythoncom.VT_NULL: "NULL", 0325 pythoncom.VT_I2: "Integer 2", 0326 pythoncom.VT_I4: "Integer 4", 0327 pythoncom.VT_R4: "Real 4", 0328 pythoncom.VT_R8: "Real 8", 0329 pythoncom.VT_CY: "CY", 0330 pythoncom.VT_DATE: "Date", 0331 pythoncom.VT_BSTR: "String", 0332 pythoncom.VT_DISPATCH: "IDispatch", 0333 pythoncom.VT_ERROR: "Error", 0334 pythoncom.VT_BOOL: "BOOL", 0335 pythoncom.VT_VARIANT: "Variant", 0336 pythoncom.VT_UNKNOWN: "IUnknown", 0337 pythoncom.VT_DECIMAL: "Decimal", 0338 pythoncom.VT_I1: "Integer 1", 0339 pythoncom.VT_UI1: "Unsigned integer 1", 0340 pythoncom.VT_UI2: "Unsigned integer 2", 0341 pythoncom.VT_UI4: "Unsigned integer 4", 0342 pythoncom.VT_I8: "Integer 8", 0343 pythoncom.VT_UI8: "Unsigned integer 8", 0344 pythoncom.VT_INT: "Integer", 0345 pythoncom.VT_UINT: "Unsigned integer", 0346 pythoncom.VT_VOID: "Void", 0347 pythoncom.VT_HRESULT: "HRESULT", 0348 pythoncom.VT_PTR: "Pointer", 0349 pythoncom.VT_SAFEARRAY: "SafeArray", 0350 pythoncom.VT_CARRAY: "C Array", 0351 pythoncom.VT_USERDEFINED: "User Defined", 0352 pythoncom.VT_LPSTR: "Pointer to string", 0353 pythoncom.VT_LPWSTR: "Pointer to Wide String", 0354 pythoncom.VT_FILETIME: "File time", 0355 pythoncom.VT_BLOB: "Blob", 0356 pythoncom.VT_STREAM: "IStream", 0357 pythoncom.VT_STORAGE: "IStorage", 0358 pythoncom.VT_STORED_OBJECT: "Stored object", 0359 pythoncom.VT_STREAMED_OBJECT: "Streamed object", 0360 pythoncom.VT_BLOB_OBJECT: "Blob object", 0361 pythoncom.VT_CF: "CF", 0362 pythoncom.VT_CLSID: "CLSID", 0363 } 0364 0365 type_flags = [ (pythoncom.VT_VECTOR, "Vector"), 0366 (pythoncom.VT_ARRAY, "Array"), 0367 (pythoncom.VT_BYREF, "ByRef"), 0368 (pythoncom.VT_RESERVED, "Reserved"), 0369 ] 0370 0371 def __init__(self, myitem): 0372 typeinfo, index = myitem 0373 self.id = typeinfo.GetFuncDesc(index)[0] 0374 name = typeinfo.GetNames(self.id)[0] 0375 HLICOM.__init__(self, myitem, name) 0376 def GetText(self): 0377 return self.name + " - Function" 0378 def MakeReturnTypeName(self, typ): 0379 justtyp = typ & pythoncom.VT_TYPEMASK 0380 try: 0381 typname = self.vartypes[justtyp] 0382 except KeyError: 0383 typname = "?Bad type?" 0384 for (flag, desc) in self.type_flags: 0385 if flag & typ: 0386 typname = "%s(%s)" % (desc, typname) 0387 return typname 0388 def MakeReturnType(self, returnTypeDesc): 0389 if type(returnTypeDesc)==type(()): 0390 first = returnTypeDesc[0] 0391 result = self.MakeReturnType(first) 0392 if first != pythoncom.VT_USERDEFINED: 0393 result = result + " " + self.MakeReturnType(returnTypeDesc[1]) 0394 return result 0395 else: 0396 return self.MakeReturnTypeName(returnTypeDesc) 0397 0398 def GetSubList(self): 0399 ret = [] 0400 typeinfo, index = self.myobject 0401 names = typeinfo.GetNames(self.id) 0402 ret.append(browser.MakeHLI(self.id, "Dispatch ID")) 0403 if len(names)>1: 0404 ret.append(browser.MakeHLI(string.join(names[1:], ", "), "Named Params")) 0405 fd = typeinfo.GetFuncDesc(index) 0406 if fd[1]: 0407 ret.append(browser.MakeHLI(fd[1], "Possible result values")) 0408 if fd[8]: 0409 typ, flags, default = fd[8] 0410 val = self.MakeReturnType(typ) 0411 if flags: 0412 val = "%s (Flags=%d, default=%s)" % (val, flags, default) 0413 ret.append(browser.MakeHLI(val, "Return Type")) 0414 0415 for argDesc in fd[2]: 0416 typ, flags, default = argDesc 0417 val = self.MakeReturnType(typ) 0418 if flags: 0419 val = "%s (Flags=%d)" % (val, flags) 0420 if default is not None: 0421 val = "%s (Default=%s)" % (val, default) 0422 ret.append(browser.MakeHLI(val, "Argument")) 0423 0424 try: 0425 fkind = self.funckinds[fd[3]] 0426 except KeyError: 0427 fkind = "Unknown" 0428 ret.append(browser.MakeHLI(fkind, "Function Kind")) 0429 try: 0430 ikind = self.invokekinds[fd[4]] 0431 except KeyError: 0432 ikind = "Unknown" 0433 ret.append(browser.MakeHLI(ikind, "Invoke Kind")) 0434 # 5 = call conv 0435 # 5 = offset vtbl 0436 ret.append(browser.MakeHLI(fd[6], "Number Optional Params")) 0437 flagDescs = [] 0438 for flag, desc in self.funcflags: 0439 if flag & fd[9]: 0440 flagDescs.append(desc) 0441 if flagDescs: 0442 ret.append(browser.MakeHLI(string.join(flagDescs, ", "), "Function Flags")) 0443 return ret 0444 0445 HLITypeKinds = { 0446 pythoncom.TKIND_ENUM : (HLITypeLibEnum, 'Enumeration'), 0447 pythoncom.TKIND_RECORD : (HLITypeLibEntry, 'Record'), 0448 pythoncom.TKIND_MODULE : (HLITypeLibEnum, 'Module'), 0449 pythoncom.TKIND_INTERFACE : (HLITypeLibMethod, 'Interface'), 0450 pythoncom.TKIND_DISPATCH : (HLITypeLibMethod, 'Dispatch'), 0451 pythoncom.TKIND_COCLASS : (HLICoClass, 'CoClass'), 0452 pythoncom.TKIND_ALIAS : (HLITypeLibEntry, 'Alias'), 0453 pythoncom.TKIND_UNION : (HLITypeLibEntry, 'Union') 0454 } 0455 0456 class HLITypeLib(HLICOM): 0457 def GetSubList(self): 0458 ret = [] 0459 ret.append(browser.MakeHLI(self.myobject, "Filename")) 0460 try: 0461 tlb = pythoncom.LoadTypeLib(self.myobject) 0462 except pythoncom.com_error: 0463 return [browser.MakeHLI("%s can not be loaded" % self.myobject)] 0464 0465 for i in range(tlb.GetTypeInfoCount()): 0466 try: 0467 ret.append(HLITypeKinds[tlb.GetTypeInfoType(i)][0]( (tlb, i) ) ) 0468 except pythoncom.com_error: 0469 ret.append(browser.MakeHLI("The type info can not be loaded!")) 0470 ret.sort() 0471 return ret 0472 0473 class HLIHeadingRegisterdTypeLibs(HLICOM): 0474 "A tree heading for registered type libraries" 0475 def GetText(self): 0476 return "Registered Type Libraries" 0477 def GetSubList(self): 0478 # Explicit lookup in the registry. 0479 ret = [] 0480 key = win32api.RegOpenKey(win32con.HKEY_CLASSES_ROOT, "TypeLib") 0481 win32ui.DoWaitCursor(1) 0482 try: 0483 num = 0 0484 while 1: 0485 try: 0486 keyName = win32api.RegEnumKey(key, num) 0487 except win32api.error: 0488 break 0489 # Enumerate all version info 0490 subKey = win32api.RegOpenKey(key, keyName) 0491 name = None 0492 try: 0493 subNum = 0 0494 bestVersion = 0.0 0495 while 1: 0496 try: 0497 versionStr = win32api.RegEnumKey(subKey, subNum) 0498 except win32api.error: 0499 break 0500 try: 0501 versionFlt = string.atof(versionStr) 0502 except ValueError: 0503 versionFlt = 0 # ???? 0504 if versionFlt > bestVersion: 0505 bestVersion = versionFlt 0506 name = win32api.RegQueryValue(subKey, versionStr) 0507 subNum = subNum + 1 0508 finally: 0509 win32api.RegCloseKey(subKey) 0510 if name is not None: 0511 ret.append(HLIRegisteredTypeLibrary((keyName, versionStr), name)) 0512 num = num + 1 0513 finally: 0514 win32api.RegCloseKey(key) 0515 win32ui.DoWaitCursor(0) 0516 ret.sort() 0517 return ret 0518 0519 def main(): 0520 from pywin.tools import hierlist 0521 root = HLIRoot("COM Browser") 0522 if sys.modules.has_key("app"): 0523 # do it in a window 0524 browser.MakeTemplate() 0525 browser.template.OpenObject(root) 0526 else: 0527 # list=hierlist.HierListWithItems( root, win32ui.IDB_BROWSER_HIER ) 0528 # dlg=hierlist.HierDialog("COM Browser",list) 0529 dlg = browser.dynamic_browser(root) 0530 dlg.DoModal() 0531 0532 0533 0534 if __name__=='__main__': 0535 main() 0536 0537 ni = pythoncom._GetInterfaceCount() 0538 ng = pythoncom._GetGatewayCount() 0539 if ni or ng: 0540 print "Warning - exiting with %d/%d objects alive" % (ni,ng) 0541 0542
Generated by PyXR 0.9.4