util.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # Utility function for wrapping objects. Centralising allows me to turn
  2. # debugging on and off for the entire package in a single spot.
  3. import sys
  4. import win32com.server.util
  5. from win32com.server.exception import Exception
  6. import winerror
  7. import win32api
  8. import os
  9. try:
  10. os.environ["DEBUG_AXDEBUG"]
  11. debugging = 1
  12. except KeyError:
  13. debugging = 0
  14. def trace(*args):
  15. if not debugging: return
  16. print(str(win32api.GetCurrentThreadId()) + ":", end=' ')
  17. for arg in args:
  18. print(arg, end=' ')
  19. print()
  20. # The AXDebugging implementation assumes that the returned COM pointers are in
  21. # some cases identical. Eg, from a C++ perspective:
  22. # p->GetSomeInterface( &p1 );
  23. # p->GetSomeInterface( &p2 );
  24. # p1==p2
  25. # By default, this is _not_ true for Python.
  26. # (Now this is only true for Document objects, and Python
  27. # now does ensure this.
  28. all_wrapped = {}
  29. def _wrap_nodebug(object, iid):
  30. return win32com.server.util.wrap(object, iid)
  31. def _wrap_debug(object, iid):
  32. import win32com.server.policy
  33. dispatcher = win32com.server.policy.DispatcherWin32trace
  34. return win32com.server.util.wrap(object, iid, useDispatcher = dispatcher)
  35. if debugging:
  36. _wrap = _wrap_debug
  37. else:
  38. _wrap = _wrap_nodebug
  39. def _wrap_remove(object, iid = None):
  40. # Old - no longer used or necessary!
  41. return
  42. def _dump_wrapped():
  43. from win32com.server.util import unwrap
  44. print("Wrapped items:")
  45. for key, items in all_wrapped.items():
  46. print(key, end=' ')
  47. try:
  48. ob = unwrap(key)
  49. print(ob, sys.getrefcount(ob))
  50. except:
  51. print("<error>")
  52. def RaiseNotImpl(who = None):
  53. if who is not None:
  54. print("********* Function %s Raising E_NOTIMPL ************" % (who))
  55. # Print a sort-of "traceback", dumping all the frames leading to here.
  56. try:
  57. 1/0
  58. except:
  59. frame = sys.exc_info()[2].tb_frame
  60. while frame:
  61. print("File: %s, Line: %d" % (frame.f_code.co_filename, frame.f_lineno))
  62. frame = frame.f_back
  63. # and raise the exception for COM
  64. raise Exception(scode=winerror.E_NOTIMPL)
  65. import win32com.server.policy
  66. class Dispatcher(win32com.server.policy.DispatcherWin32trace):
  67. def __init__(self, policyClass, object):
  68. win32com.server.policy.DispatcherTrace.__init__(self, policyClass, object)
  69. import win32traceutil # Sets up everything.
  70. # print "Object with win32trace dispatcher created (object=%s)" % `object`
  71. def _QueryInterface_(self, iid):
  72. rc = win32com.server.policy.DispatcherBase._QueryInterface_(self, iid)
  73. # if not rc:
  74. # self._trace_("in _QueryInterface_ with unsupported IID %s (%s)\n" % (IIDToInterfaceName(iid),iid))
  75. return rc
  76. def _Invoke_(self, dispid, lcid, wFlags, args):
  77. print("In Invoke with", dispid, lcid, wFlags, args, "with object",self.policy._obj_)
  78. try:
  79. rc = win32com.server.policy.DispatcherBase._Invoke_(self, dispid, lcid, wFlags, args)
  80. # print "Invoke of", dispid, "returning", rc
  81. return rc
  82. except Exception:
  83. t, v, tb = sys.exc_info()
  84. tb = None # A cycle
  85. scode = v.scode
  86. try:
  87. desc = " (" + str(v.description) + ")"
  88. except AttributeError:
  89. desc = ""
  90. print("*** Invoke of %s raised COM exception 0x%x%s" % (dispid, scode, desc))
  91. except:
  92. print("*** Invoke of %s failed:" % dispid)
  93. typ, val, tb = sys.exc_info()
  94. import traceback
  95. traceback.print_exception(typ, val, tb)
  96. raise