import sys, os, base64, struct, time from types import TupleType import distutils from distutils.command.bdist_wininst import bdist_wininst from distutils.dir_util import create_tree, remove_tree # (display, metadata_attr) or (display, [attr1, attr2...]) _metadata_names = [('Name', 'name'), ('Version', 'version'), ('Summary', 'description'), ('Homepage', 'url'), ('Author', ('maintainer', 'author')), ('Email', ('maintainer_email', 'author_email')), ('License', ('license', 'licence')), ] # This is, for the most part, the wininst command from Python 2.1.2 and 2.2 # modified to handle our installation scheme and run with Python 2.0 and 2.1 class BDistWininst(bdist_wininst): command_name = 'bdist_wininst' def initialize_options(self): # Features missing form distutils prior Python 2.1.2 self.title = None self.bitmap = None return bdist_wininst.initialize_options(self) def finalize_options(self): if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'wininst-%s' % sys.version[:3]) return bdist_wininst.finalize_options(self) def run(self): if (sys.platform != "win32" and (self.distribution.has_ext_modules() or self.distribution.has_c_libraries())): raise DistutilsPlatformError \ ("distribution contains extensions and/or C libraries; " "must be compiled on a Windows 32 platform") self.run_command('build') install = self.reinitialize_command('install') install.root = self.bdist_dir install.warn_dir = 0 install.with_docs = 1 # Use a custom scheme for the zip-file, because we have to decide # at installation time which scheme to use. install.install_platlib = install.install_purelib = 'PURELIB' install.install_headers = 'HEADERS/Include/$dist_name' install_lib = self.reinitialize_command('install_lib') # we do not want to include pyc or pyo files install_lib.compile = 0 install_lib.optimize = 0 self.announce("installing to %s" % self.bdist_dir) install.ensure_finalized() install.run() # And make an archive relative to the root of the # pseudo-installation tree. from tempfile import mktemp archive_basename = mktemp() fullname = self.distribution.get_fullname() arcname = self.make_archive(archive_basename, "zip", root_dir=self.bdist_dir) # create an exe containing the zip-file self.create_exe(arcname, fullname, self.bitmap) # remove the zip-file again self.announce("removing temporary file '%s'" % arcname) os.remove(arcname) if not self.keep_temp: remove_tree(self.bdist_dir, self.verbose, self.dry_run) return def create_exe (self, arcname, fullname, bitmap=None): self.mkpath(self.dist_dir) cfgdata = self.get_inidata() if self.target_version: # if we create an installer for a specific python version, # it's better to include this in the name installer_name = os.path.join(self.dist_dir, "%s.win32-py%s.exe" % (fullname, self.target_version)) else: installer_name = os.path.join(self.dist_dir, "%s.win32.exe" % fullname) self.announce("creating %s" % installer_name) if bitmap: bitmapdata = open(bitmap, "rb").read() bitmaplen = len(bitmapdata) else: bitmaplen = 0 file = open(installer_name, "wb") file.write(base64.decodestring(EXEDATA)) if bitmap: file.write(bitmapdata) file.write(cfgdata) header = struct.pack("