1
|
1 |
# Copyright (C) 2005, Giovanni Bajo
|
|
2 |
# Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
|
|
3 |
#
|
|
4 |
# This program is free software; you can redistribute it and/or
|
|
5 |
# modify it under the terms of the GNU General Public License
|
|
6 |
# as published by the Free Software Foundation; either version 2
|
|
7 |
# of the License, or (at your option) any later version.
|
|
8 |
#
|
|
9 |
# This program is distributed in the hope that it will be useful,
|
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12 |
# GNU General Public License for more details.
|
|
13 |
#
|
|
14 |
# You should have received a copy of the GNU General Public License
|
|
15 |
# along with this program; if not, write to the Free Software
|
|
16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
17 |
import string, os, sys, win32api, Makespec
|
|
18 |
|
|
19 |
modspec = """\
|
|
20 |
%(mod)s.%(klass)s._reg_class_spec_ = "%(mod)s.%(klass)s"
|
|
21 |
if (not hasattr(%(mod)s.%(klass)s, '_reg_clsctx_') or
|
|
22 |
%(mod)s.%(klass)s._reg_clsctx_ & pythoncom.CLSCTX_INPROC):
|
|
23 |
%(mod)s.%(klass)s._reg_options_ = {'InprocServer32':
|
|
24 |
os.path.abspath(
|
|
25 |
os.path.join(
|
|
26 |
os.path.dirname(sys.executable), "%(dllname)s"))}
|
|
27 |
""" #mod, klass, dllname
|
|
28 |
tmplt = """\
|
|
29 |
import sys
|
|
30 |
import string
|
|
31 |
import os
|
|
32 |
inprocess = getattr(sys, 'frozen', None)
|
|
33 |
%(modimports)s
|
|
34 |
|
|
35 |
register = 0
|
|
36 |
for i in range(1, len(sys.argv)):
|
|
37 |
arg = sys.argv[i]
|
|
38 |
if string.find(arg, "reg") > -1:
|
|
39 |
register = 1
|
|
40 |
if arg == '/unreg':
|
|
41 |
sys.argv[i] = '--unregister'
|
|
42 |
if register:
|
|
43 |
import pythoncom
|
|
44 |
pythoncom.frozen = 1
|
|
45 |
%(modspecs)s
|
|
46 |
from win32com.server import register
|
|
47 |
register.UseCommandLine(%(regspecs)s, %(flags)s)
|
|
48 |
else:
|
|
49 |
#older Python's need to force this import before pythoncom does it
|
|
50 |
import win32com.server.policy
|
|
51 |
if inprocess == 'dll':
|
|
52 |
pass
|
|
53 |
else:
|
|
54 |
import win32com.server.localserver
|
|
55 |
win32com.server.localserver.main()
|
|
56 |
|
|
57 |
""" #modimports, modspecs regspecs, flags
|
|
58 |
|
|
59 |
def create(scripts, debug, verbosity, workdir, ascii=0):
|
|
60 |
infos = [] # (path, module, klasses)
|
|
61 |
for script in scripts:
|
|
62 |
infos.append(analscriptname(script))
|
|
63 |
outfnm = 'drive%s.py' % infos[0][1]
|
|
64 |
dllname = 'drive%s.dll' % infos[0][1]
|
|
65 |
if not os.path.exists(workdir):
|
|
66 |
os.makedirs(workdir)
|
|
67 |
outfnm = os.path.join(workdir, outfnm)
|
|
68 |
outf = open(outfnm, 'w')
|
|
69 |
modspecs = []
|
|
70 |
regspecs = []
|
|
71 |
modimports = []
|
|
72 |
flags = 'debug=0, quiet=%s' % (verbosity==0)
|
|
73 |
paths = []
|
|
74 |
for path, module, klasses in infos:
|
|
75 |
if path:
|
|
76 |
paths.append(path)
|
|
77 |
for klass in klasses:
|
|
78 |
d = { 'mod':module, 'klass':klass, 'dllname':dllname }
|
|
79 |
modspecs.append(modspec % d)
|
|
80 |
regspecs.append('%(mod)s.%(klass)s' % d)
|
|
81 |
modimports.append("import %(mod)s" % d)
|
|
82 |
for i in range(len(paths)):
|
|
83 |
path = paths[i]
|
|
84 |
paths[i] = win32api.GetShortPathName(os.path.normpath(path))
|
|
85 |
modspecs = string.join(modspecs, '\n')
|
|
86 |
modimports = string.join(modimports, '\n')
|
|
87 |
regspecs = string.join(regspecs, ', ')
|
|
88 |
d = { 'modspecs':modspecs,
|
|
89 |
'regspecs':regspecs,
|
|
90 |
'modimports':modimports,
|
|
91 |
'flags':flags }
|
|
92 |
outf.write( tmplt % d )
|
|
93 |
outf.close()
|
|
94 |
print "**********************************"
|
|
95 |
print "Driver script %s created" % outfnm
|
|
96 |
specfnm = Makespec.main([outfnm], console=debug, debug=debug,
|
|
97 |
workdir=workdir, pathex=paths, comserver=1, ascii=ascii)
|
|
98 |
print "Spec file %s created" % specfnm
|
|
99 |
|
|
100 |
def analscriptname(script):
|
|
101 |
# return (path, module, klasses)
|
|
102 |
path, basename = os.path.split(script)
|
|
103 |
module = os.path.splitext(basename)[0]
|
|
104 |
while ispkgdir(path):
|
|
105 |
path, basename = os.path.split(path)
|
|
106 |
module = '%s.%s' % (basename, module)
|
|
107 |
try:
|
|
108 |
__import__(module)
|
|
109 |
except ImportError:
|
|
110 |
oldpath = sys.path[:]
|
|
111 |
sys.path.insert(0, path)
|
|
112 |
try:
|
|
113 |
__import__(module)
|
|
114 |
finally:
|
|
115 |
sys.path = oldpath
|
|
116 |
else:
|
|
117 |
path = None
|
|
118 |
m = sys.modules[module]
|
|
119 |
klasses = []
|
|
120 |
for nm, thing in m.__dict__.items():
|
|
121 |
if hasattr(thing, '_reg_clsid_'):
|
|
122 |
klasses.append(nm)
|
|
123 |
return (path, module, klasses)
|
|
124 |
|
|
125 |
def ispkgdir(path):
|
|
126 |
try:
|
|
127 |
open(os.path.join(path, '__init__.py'), 'r')
|
|
128 |
except IOError:
|
|
129 |
try:
|
|
130 |
open(os.path.join(path, '__init__.pyc'), 'rb')
|
|
131 |
except IOError:
|
|
132 |
return 0
|
|
133 |
return 1
|
|
134 |
|
|
135 |
usage = """\
|
|
136 |
Usage: python %s [options] <scriptname>.py [<scriptname>.py ...]
|
|
137 |
--debug -> use debug console build and register COM servers with debug
|
|
138 |
--verbose -> use verbose flag in COM server registration
|
|
139 |
--out dir -> generate script and spec file in dir
|
|
140 |
|
|
141 |
The next step is to run Build.py against the generated spec file.
|
|
142 |
See doc/Tutorial.html for details.
|
|
143 |
"""
|
|
144 |
|
|
145 |
if __name__ == '__main__':
|
|
146 |
#scripts, debug, verbosity, workdir
|
|
147 |
debug = verbosity = ascii = 0
|
|
148 |
workdir = '.'
|
|
149 |
import getopt
|
|
150 |
opts, args = getopt.getopt(sys.argv[1:], '', ['debug', 'verbose', 'ascii', 'out='])
|
|
151 |
for opt, val in opts:
|
|
152 |
if opt == '--debug':
|
|
153 |
debug = 1
|
|
154 |
elif opt == '--verbose':
|
|
155 |
verbosity = 1
|
|
156 |
elif opt == '--out':
|
|
157 |
workdir = val
|
|
158 |
elif opt == '--ascii':
|
|
159 |
ascii = 1
|
|
160 |
else:
|
|
161 |
print usage % sys.argv[0]
|
|
162 |
sys.exit(1)
|
|
163 |
if not args:
|
|
164 |
print usage % sys.argv[0]
|
|
165 |
else:
|
|
166 |
create(args, debug, verbosity, workdir, ascii)
|