File size: 3,880 Bytes
10865e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# 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("<error>")


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