# Utility function for wrapping objects. Centralising allows me to turn # debugging on and off for the entire package in a single spot. import os import sys import win32api import win32com.server.util import winerror from win32com.server.exception import Exception try: os.environ["DEBUG_AXDEBUG"] debugging = 1 except KeyError: debugging = 0 def trace(*args): if not debugging: return print(str(win32api.GetCurrentThreadId()) + ":", end=" ") for arg in args: print(arg, end=" ") print() # The AXDebugging implementation assumes that the returned COM pointers are in # some cases identical. Eg, from a C++ perspective: # p->GetSomeInterface( &p1 ); # p->GetSomeInterface( &p2 ); # p1==p2 # By default, this is _not_ true for Python. # (Now this is only true for Document objects, and Python # now does ensure this. all_wrapped = {} def _wrap_nodebug(object, iid): return win32com.server.util.wrap(object, iid) def _wrap_debug(object, iid): import win32com.server.policy dispatcher = win32com.server.policy.DispatcherWin32trace return win32com.server.util.wrap(object, iid, useDispatcher=dispatcher) if debugging: _wrap = _wrap_debug else: _wrap = _wrap_nodebug def _wrap_remove(object, iid=None): # Old - no longer used or necessary! return def _dump_wrapped(): from win32com.server.util import unwrap print("Wrapped items:") for key, items in all_wrapped.items(): print(key, end=" ") try: ob = unwrap(key) print(ob, sys.getrefcount(ob)) except: print("") def RaiseNotImpl(who=None): if who is not None: print("********* Function %s Raising E_NOTIMPL ************" % (who)) # Print a sort-of "traceback", dumping all the frames leading to here. try: 1 / 0 except: frame = sys.exc_info()[2].tb_frame while frame: print("File: %s, Line: %d" % (frame.f_code.co_filename, frame.f_lineno)) frame = frame.f_back # and raise the exception for COM raise Exception(scode=winerror.E_NOTIMPL) import win32com.server.policy class Dispatcher(win32com.server.policy.DispatcherWin32trace): def __init__(self, policyClass, object): win32com.server.policy.DispatcherTrace.__init__(self, policyClass, object) import win32traceutil # Sets up everything. # print "Object with win32trace dispatcher created (object=%s)" % `object` def _QueryInterface_(self, iid): rc = win32com.server.policy.DispatcherBase._QueryInterface_(self, iid) # if not rc: # self._trace_("in _QueryInterface_ with unsupported IID %s (%s)\n" % (IIDToInterfaceName(iid),iid)) return rc def _Invoke_(self, dispid, lcid, wFlags, args): print( "In Invoke with", dispid, lcid, wFlags, args, "with object", self.policy._obj_, ) try: rc = win32com.server.policy.DispatcherBase._Invoke_( self, dispid, lcid, wFlags, args ) # print "Invoke of", dispid, "returning", rc return rc except Exception: t, v, tb = sys.exc_info() tb = None # A cycle scode = v.scode try: desc = " (" + str(v.description) + ")" except AttributeError: desc = "" print( "*** Invoke of %s raised COM exception 0x%x%s" % (dispid, scode, desc) ) except: print("*** Invoke of %s failed:" % dispid) typ, val, tb = sys.exc_info() import traceback traceback.print_exception(typ, val, tb) raise