# A setup script showing how to extend py2exe. # # In this case, the py2exe command is subclassed to create an installation # script for InnoSetup, which can be compiled with the InnoSetup compiler # to a single file windows installer. # # By default, the installer will be created as dist\Output\setup.exe. from distutils.core import setup import py2exe import sys ################################################################ # A program using wxPython # The manifest will be inserted as resource into polymer.exe. This # gives the controls the Windows XP appearance (if run on XP ;-) # # Another option would be to store if in a file named # polymer.exe.manifest, and probably copy it with the data_files # option. # manifest_template = ''' %(prog)s Program ''' RT_MANIFEST = 24 ################################################################ # arguments for the setup() call polymer = dict( script = "polymer.py", other_resources = [(RT_MANIFEST, 1, manifest_template % dict(prog="polymer"))], icon_resources = [(1,r'polymer\invsys.ico')], dest_base = r"prog\polymer") polymerd = dict( script = "polymer.py", other_resources = [(RT_MANIFEST, 1, manifest_template % dict(prog="polymerd"))], icon_resources = [(1,r'polymer\invsys.ico')], dest_base = r"prog\polymerd") zipfile = r"lib\shardlib" includes = ['encodings','encodings.*','dbhash'] options = {"py2exe": {"compressed": 1, "optimize": 2, "includes": includes}} ################################################################ import os class InnoScript: def __init__(self, name, lib_dir, dist_dir, windows_exe_files = [], console_exe_files = [], lib_files = [], version = "Subversion r614"): self.lib_dir = lib_dir self.dist_dir = dist_dir if not self.dist_dir[-1] in "\\/": self.dist_dir += "\\" self.name = name self.version = version self.windows_exe_files = [self.chop(p) for p in windows_exe_files] self.console_exe_files = [self.chop(p) for p in console_exe_files] self.lib_files = [self.chop(p) for p in lib_files] def chop(self, pathname): assert pathname.startswith(self.dist_dir) return pathname[len(self.dist_dir):] def create(self, pathname="dist\\polymer.iss"): self.pathname = pathname ofi = self.file = open(pathname, "w") print >> ofi, "; WARNING: This script has been created by py2exe. Changes to this script" print >> ofi, "; will be overwritten the next time py2exe is run!" print >> ofi, r"[Setup]" print >> ofi, r"AppName=%s" % self.name print >> ofi, r"AppVerName=%s %s" % (self.name, self.version) print >> ofi, r"DefaultDirName={pf}\%s" % self.name print >> ofi, r"DefaultGroupName=%s" % self.name print >> ofi, r"Compression=lzma/max" print >> ofi print >> ofi, "[Types]" print >> ofi, 'Name: "typical"; Description: "Typical Install"' print >> ofi, 'Name: "full"; Description: "Full Install"' print >> ofi, 'Name: "custom"; Description: "Customize Install"; Flags: iscustom' print >> ofi print >> ofi, '[Components]' print >> ofi, 'Name: "base"; Description: "Base Files"; Types: typical full custom; Flags: fixed' print >> ofi, 'Name: "polymer"; Description: "Infotrope Polymer"; Types: typical full custom; Flags: fixed' print >> ofi, 'Name: "debug"; Description: "Infotrope Polymer (console)"; Types: full custom' print >> ofi print >> ofi, r"[Files]" for path in self.console_exe_files: print >> ofi, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion; Components: debug' % (path, os.path.dirname(path)) for path in self.windows_exe_files: print >> ofi, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion; Components: polymer' % (path, os.path.dirname(path)) for path in self.lib_files: print >> ofi, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion; Components: base' % (path, os.path.dirname(path)) print >> ofi print >> ofi, r"[Icons]" for path in self.windows_exe_files: print >> ofi, r'Name: "{group}\%s"; Filename: "{app}\%s"; Components: polymer' % \ (self.name, path) for path in self.console_exe_files: print >> ofi, r'Name: "{group}\%s"; Filename: "{app}\%s"; Components: debug' % \ (self.name + ' (console)', path) print >> ofi, 'Name: "{group}\Uninstall %s"; Filename: "{uninstallexe}"; Components: base' % self.name def compile(self): try: import ctypes except ImportError: try: import win32api except ImportError: import os os.startfile(self.pathname) else: print "Ok, using win32api." win32api.ShellExecute(0, "compile", self.pathname, None, None, 0) else: print "Cool, you have ctypes installed." res = ctypes.windll.shell32.ShellExecuteA(0, "compile", self.pathname, None, None, 0) if res < 32: raise RuntimeError, "ShellExecute failed, error %d" % res ################################################################ from py2exe.build_exe import py2exe class build_installer(py2exe): # This class first builds the exe file(s), then creates a Windows installer. # You need InnoSetup for it. def run(self): # First, let py2exe do it's work. py2exe.run(self) lib_dir = self.lib_dir dist_dir = self.dist_dir # create the Installer, using the files py2exe has created. script = InnoScript("Infotrope Polymer", lib_dir, dist_dir, self.windows_exe_files, self.console_exe_files, self.lib_files) print "*** creating the inno setup script***" script.create() print "*** compiling the inno setup script***" script.compile() # Note: By default the final setup.exe will be in an Output subdirectory. ################################################################ import glob import os iconography = [] for fs in os.listdir( r'polymer\icons' ): iconography.append( (os.path.join('data', 'icons', fs), glob.glob( os.path.join( r'polymer\icons', fs, '*.png' ) )) ) iconography.append( ( r'data', glob.glob(r'polymer\*.bmp') + [r'polymer\invsys.ico'] ) ) iconography = [ x for x in iconography if len(x[1]) ] # Iconography has to add in zlib, too. iconography.append( ( r'prog', [r'infotrope\zlibwapi.dll'] ) ) #print "Iconography:",`iconography` #import sys #sys.exit(0) setup( options = options, # The lib directory contains everything except the executables and the python dll. zipfile = zipfile, windows = [polymer], console = [polymerd], data_files = iconography, # use out build_installer class as extended py2exe build command cmdclass = {"py2exe": build_installer}, )