boot_com_servers.py
4.36 KB
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
# This support script is executed as the entry point for py2exe.
import sys
import win32api
if 0:
################################################################
# XXX Remove later!
class LOGGER:
def __init__(self):
self.softspace = None
self.ofi = open(r"c:\comerror.txt", "w")
def write(self, text):
self.ofi.write(text)
self.ofi.flush()
sys.stderr = sys.stdout = LOGGER()
sys.stderr.write("PATH is %s\n" % sys.path)
################################################################
# tell the win32 COM registering/unregistering code that we're inside
# of an EXE/DLL
import pythoncom
if not hasattr(sys, "frozen"):
# standard exes have none.
sys.frozen = pythoncom.frozen = 1
else:
# com DLLs already have sys.frozen set to 'dll'
pythoncom.frozen = sys.frozen
# Add some extra imports here, just to avoid putting them as "hidden imports"
# anywhere else - this script has the best idea about what it needs.
# (and hidden imports are currently disabled :)
import win32com.server.policy, win32com.server.util
# Patchup sys.argv for our DLL
if sys.frozen=="dll" and not hasattr(sys, "argv"):
sys.argv = [win32api.GetModuleFileName(sys.frozendllhandle)]
# We assume that py2exe has magically set com_module_names
# to the module names that expose the COM objects we host.
# Note that here all the COM modules for the app are imported - hence any
# environment changes (such as sys.stderr redirection) will happen now.
com_modules = []
try:
for name in com_module_names:
__import__(name)
com_modules.append(sys.modules[name])
except NameError:
print "This script is designed to be run from inside py2exe"
sys.exit(1)
del name
def get_classes(module):
return [ob
for ob in module.__dict__.values()
if hasattr(ob, "_reg_progid_")
]
def DllRegisterServer():
# Enumerate each module implementing an object
import win32com.server.register
for mod in com_modules:
# register each class
win32com.server.register.RegisterClasses(*get_classes(mod))
# see if the module has a custom registration function.
extra_fun = getattr(mod, "DllRegisterServer", None)
if extra_fun is not None:
extra_fun()
def DllUnregisterServer():
# Enumerate each module implementing an object
import win32com.server.register
for mod in com_modules:
# see if the module has a custom unregister function.
extra_fun = getattr(mod, "DllUnregisterServer", None)
if extra_fun is not None:
extra_fun()
# and unregister each class
win32com.server.register.UnregisterClasses(*get_classes(mod))
def DllInstall(bInstall, cmdline):
# Enumerate each module implementing an object
for mod in com_modules:
# see if the module has the function.
extra_fun = getattr(mod, "DllInstall", None)
if extra_fun is not None:
extra_fun(bInstall, cmdline)
# Mainline code - executed always
# If we are running as a .EXE, check and process command-line args
if sys.frozen != "dll":
import win32com.server.localserver
for i in range(1, len(sys.argv)):
arg = sys.argv[i].lower()
# support "exe /regserver"
if arg.find("/reg") > -1 or arg.find("--reg") > -1 \
or arg.find("-regserver") > -1:
DllRegisterServer()
break
# support "exe /unreg...r"
if arg.find("/unreg") > -1 or arg.find("--unreg") > -1 \
or arg.find("-unregserver") > -1:
DllUnregisterServer()
break
# MS seems to like /automate to run the class factories.
if arg.find("/automate") > -1:
clsids = []
for m in com_modules:
for k in get_classes(m):
clsids.append(k._reg_clsid_)
# Fire up the class factories, and run the servers
win32com.server.localserver.serve(clsids)
# All servers dead - we are done!
break
else:
# You could do something else useful here.
win32api.MessageBox(0,
"This program hosts a COM Object and\r\n"
"is started automatically\r\n"
"(or maybe you want /register or /unregister?)",
"COM Object")