144b345460a9c6e38154df8bfc2afe1d26a35849bMartin v. Löwis# Copyright (C) 2005, 2006 Martin von Löwis 2fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis# Licensed to PSF under a Contributor Agreement. 3fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis# The bdist_wininst command proper 4fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis# based on bdist_wininst 5fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis""" 6fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. LöwisImplements the bdist_msi command. 7fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis""" 8fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 93679727939a9d25ccfe057e71e8a4b8be73d47ceTarek Ziadéimport sys, os 10fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom distutils.core import Command 11fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom distutils.dir_util import remove_tree 123679727939a9d25ccfe057e71e8a4b8be73d47ceTarek Ziadéfrom distutils.sysconfig import get_python_version 13fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom distutils.version import StrictVersion 14fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom distutils.errors import DistutilsOptionError 153679727939a9d25ccfe057e71e8a4b8be73d47ceTarek Ziadéfrom distutils.util import get_platform 16fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom distutils import log 17fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisimport msilib 18477c8d5e70240744d24631b18341ad892c8a8e1cThomas Woutersfrom msilib import schema, sequence, text 19fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisfrom msilib import Directory, Feature, Dialog, add_data 20fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 21fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwisclass PyDialog(Dialog): 22fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Dialog class with a fixed layout: controls at the top, then a ruler, 23fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis then a list of buttons: back, next, cancel. Optionally a bitmap at the 24fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis left.""" 25fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def __init__(self, *args, **kw): 26fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Dialog(database, name, x, y, w, h, attributes, title, first, 27fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis default, cancel, bitmap=true)""" 28fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis Dialog.__init__(self, *args) 29fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ruler = self.h - 36 303679727939a9d25ccfe057e71e8a4b8be73d47ceTarek Ziadé bmwidth = 152*ruler/328 31fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #if kw.get("bitmap", True): 32fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") 33fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.line("BottomLine", 0, ruler, self.w, 0) 34fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 35fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def title(self, title): 36fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Set the title text of the dialog at the top." 37fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix, 38fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # text, in VerdanaBold10 39fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.text("Title", 15, 10, 320, 60, 0x30003, 40fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis r"{\VerdanaBold10}%s" % title) 41fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 42fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def back(self, title, next, name = "Back", active = 1): 43fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Add a back button with a given title, the tab-next button, 44fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis its name in the Control table, possibly initially disabled. 45fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 46fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis Return the button, so that events can be associated""" 47fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if active: 48fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 3 # Visible|Enabled 49fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis else: 50fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 1 # Visible 51fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next) 52fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 53fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def cancel(self, title, next, name = "Cancel", active = 1): 54fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Add a cancel button with a given title, the tab-next button, 55fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis its name in the Control table, possibly initially disabled. 56fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 57fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis Return the button, so that events can be associated""" 58fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if active: 59fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 3 # Visible|Enabled 60fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis else: 61fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 1 # Visible 62fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next) 63fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 64fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def next(self, title, next, name = "Next", active = 1): 65fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Add a Next button with a given title, the tab-next button, 66fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis its name in the Control table, possibly initially disabled. 67fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 68fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis Return the button, so that events can be associated""" 69fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if active: 70fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 3 # Visible|Enabled 71fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis else: 72fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis flags = 1 # Visible 73fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next) 74fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 75fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def xbutton(self, name, title, next, xpos): 76fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Add a button with a given title, the tab-next button, 77fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis its name in the Control table, giving its x position; the 78fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis y-position is aligned with the other buttons. 79fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 80fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis Return the button, so that events can be associated""" 81fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next) 82fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 835b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winterclass bdist_msi(Command): 84fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 85fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis description = "create a Microsoft Installer (.msi) binary distribution" 86fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 87fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_options = [('bdist-dir=', None, 88fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "temporary directory for creating the distribution"), 895e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes ('plat-name=', 'p', 905e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes "platform name to embed in generated filenames " 915e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes "(default: %s)" % get_platform()), 92fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('keep-temp', 'k', 93fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "keep the pseudo-installation tree around after " + 94fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "creating the distribution archive"), 95fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('target-version=', None, 96fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "require a specific python version" + 97fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis " on the target system"), 98fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('no-target-compile', 'c', 99fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "do not compile .py to .pyc on the target system"), 100fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('no-target-optimize', 'o', 101fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "do not compile .py to .pyo (optimized)" 102fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "on the target system"), 103fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('dist-dir=', 'd', 104fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "directory to put final built distributions in"), 105fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('skip-build', None, 106fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "skip rebuilding everything (for testing/debugging)"), 107fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('install-script=', None, 108fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "basename of installation script to be run after" 109fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "installation or before deinstallation"), 110fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ('pre-install-script=', None, 111fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Fully qualified filename of a script to be run before " 112fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "any files are installed. This script need not be in the " 113fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "distribution"), 114fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ] 115fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 116fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', 117fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 'skip-build'] 118fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 11993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard all_versions = ['2.0', '2.1', '2.2', '2.3', '2.4', 12093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard '2.5', '2.6', '2.7', '2.8', '2.9', 12193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard '3.0', '3.1', '3.2', '3.3', '3.4', 12293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard '3.5', '3.6', '3.7', '3.8', '3.9'] 12393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard other_version = 'X' 12493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 1255b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter def initialize_options(self): 126fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.bdist_dir = None 1275e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes self.plat_name = None 128fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.keep_temp = 0 129fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.no_target_compile = 0 130fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.no_target_optimize = 0 131fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.target_version = None 132fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.dist_dir = None 133fbe37dfffe501973b1e998bca948748097857179Éric Araujo self.skip_build = None 134fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.install_script = None 135fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.pre_install_script = None 13693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.versions = None 137fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 1385b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter def finalize_options(self): 139fbe37dfffe501973b1e998bca948748097857179Éric Araujo self.set_undefined_options('bdist', ('skip_build', 'skip_build')) 140fbe37dfffe501973b1e998bca948748097857179Éric Araujo 141fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.bdist_dir is None: 142fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis bdist_base = self.get_finalized_command('bdist').bdist_base 143fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.bdist_dir = os.path.join(bdist_base, 'msi') 144fbe37dfffe501973b1e998bca948748097857179Éric Araujo 145fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis short_version = get_python_version() 146403117aa606438427aa9f9dc72271d40bc0ba0b2Martin v. Löwis if (not self.target_version) and self.distribution.has_ext_modules(): 147403117aa606438427aa9f9dc72271d40bc0ba0b2Martin v. Löwis self.target_version = short_version 148fbe37dfffe501973b1e998bca948748097857179Éric Araujo 149fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.target_version: 15093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.versions = [self.target_version] 151fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not self.skip_build and self.distribution.has_ext_modules()\ 152fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis and self.target_version != short_version: 1535b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter raise DistutilsOptionError( 15456be37cef2c102190b88c015ca9820821f35792aGeorg Brandl "target version can only be %s, or the '--skip-build'" 1555b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter " option must be specified" % (short_version,)) 156fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis else: 15793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.versions = list(self.all_versions) 158fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 1595e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes self.set_undefined_options('bdist', 1605e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes ('dist_dir', 'dist_dir'), 1615e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes ('plat_name', 'plat_name'), 1625e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes ) 163fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 164fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.pre_install_script: 1655b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter raise DistutilsOptionError( 1665b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter "the pre-install-script feature is not yet implemented") 167fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 168fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.install_script: 169fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis for script in self.distribution.scripts: 170fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.install_script == os.path.basename(script): 171fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis break 172fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis else: 1735b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter raise DistutilsOptionError( 1745b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter "install_script '%s' not found in scripts" 1755b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter % self.install_script) 176fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.install_script_key = None 177fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 1785b7e9d76f39dbf63573519c178835f72e5a5027aCollin Winter def run(self): 179fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not self.skip_build: 180fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.run_command('build') 181fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 182fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install = self.reinitialize_command('install', reinit_subcommands=1) 183fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install.prefix = self.bdist_dir 184fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install.skip_build = self.skip_build 185fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install.warn_dir = 0 186fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 187fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install_lib = self.reinitialize_command('install_lib') 188fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # we do not want to include pyc or pyo files 189fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install_lib.compile = 0 190fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install_lib.optimize = 0 191fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 192fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.distribution.has_ext_modules(): 193fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # If we are building an installer for a Python version other 194fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # than the one we are currently running, then we need to ensure 195fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # our build_lib reflects the other Python version rather than ours. 196fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Note that for target_version!=sys.version, we must have skipped the 197fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # build step, so there is no issue with enforcing the build of this 198fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # version. 199fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis target_version = self.target_version 200fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not target_version: 201fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis assert self.skip_build, "Should have already checked this" 202885bdc4946890f4bb80557fab80c3874b2cc4d39Serhiy Storchaka target_version = '%d.%d' % sys.version_info[:2] 2035e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes plat_specifier = ".%s-%s" % (self.plat_name, target_version) 204fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis build = self.get_finalized_command('build') 205fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis build.build_lib = os.path.join(build.build_base, 206fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 'lib' + plat_specifier) 207fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 208fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis log.info("installing to %s", self.bdist_dir) 209fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install.ensure_finalized() 210fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 211fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # avoid warning of 'install_lib' about installing 212fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # into a directory not in sys.path 213fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) 214fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 215fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis install.run() 216fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 217fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis del sys.path[0] 218fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 219fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.mkpath(self.dist_dir) 220fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fullname = self.distribution.get_fullname() 221fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis installer_name = self.get_installer_filename(fullname) 222fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis installer_name = os.path.abspath(installer_name) 223fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if os.path.exists(installer_name): os.unlink(installer_name) 224fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 225fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis metadata = self.distribution.metadata 226fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis author = metadata.author 227fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not author: 228fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis author = metadata.maintainer 229fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not author: 230fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis author = "UNKNOWN" 231fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis version = metadata.get_version() 232fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # ProductVersion must be strictly numeric 233fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # XXX need to deal with prerelease versions 234fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis sversion = "%d.%d.%d" % StrictVersion(version).version 235fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Prefix ProductName with Python x.y, so that 236fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # it sorts together with the other Python packages 237fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # in Add-Remove-Programs (APR) 23893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard fullname = self.distribution.get_fullname() 23993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if self.target_version: 24093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard product_name = "Python %s %s" % (self.target_version, fullname) 24193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else: 24293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard product_name = "Python %s" % (fullname) 243fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.db = msilib.init_database(installer_name, schema, 244e8d09e581816aa7fdb812801c79e8f6bc55dc134Tim Peters product_name, msilib.gen_uuid(), 245fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis sversion, author) 246fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis msilib.add_tables(self.db, sequence) 247fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis props = [('DistVersion', version)] 248fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis email = metadata.author_email or metadata.maintainer_email 249fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if email: 250fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis props.append(("ARPCONTACT", email)) 251fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if metadata.url: 252fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis props.append(("ARPURLINFOABOUT", metadata.url)) 253fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if props: 254fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, 'Property', props) 255fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 256fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.add_find_python() 257fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.add_files() 258fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.add_scripts() 259fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.add_ui() 260fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis self.db.Commit() 261fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 262fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if hasattr(self.distribution, 'dist_files'): 263a420c820fe243cbc0d729e9c60f8a93810e973a7Éric Araujo tup = 'bdist_msi', self.target_version or 'any', fullname 26493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.distribution.dist_files.append(tup) 265fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 266fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if not self.keep_temp: 267fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis remove_tree(self.bdist_dir, dry_run=self.dry_run) 268fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 269fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def add_files(self): 270fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis db = self.db 271fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cab = msilib.CAB("distfiles") 272fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis rootdir = os.path.abspath(self.bdist_dir) 27393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 274fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir") 27593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard f = Feature(db, "Python", "Python", "Everything", 27693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 0, 1, directory="TARGETDIR") 27793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 27893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard items = [(f, root, '')] 27993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for version in self.versions + [self.other_version]: 28093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard target = "TARGETDIR" + version 28193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard name = default = "Python" + version 28293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard desc = "Everything" 28393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if version is self.other_version: 28493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard title = "Python from another location" 28593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard level = 2 28693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else: 28793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard title = "Python %s from registry" % version 28893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard level = 1 28993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard f = Feature(db, name, title, desc, 1, level, directory=target) 29093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard dir = Directory(db, cab, root, rootdir, target, default) 29193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard items.append((f, dir, version)) 292fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis db.Commit() 29393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 29493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard seen = {} 29593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for feature, dir, version in items: 29693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard todo = [dir] 29793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard while todo: 29893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard dir = todo.pop() 29993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for file in os.listdir(dir.absolute): 30093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard afile = os.path.join(dir.absolute, file) 30193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if os.path.isdir(afile): 30293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard short = "%s|%s" % (dir.make_short(file), file) 30393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard default = file + version 30493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard newdir = Directory(db, cab, dir, file, default, short) 30593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard todo.append(newdir) 30693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else: 30793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if not dir.component: 30893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard dir.start_component(dir.logical, feature, 0) 30993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if afile not in seen: 31093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard key = seen[afile] = dir.add_file(file) 31193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if file==self.install_script: 31293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if self.install_script_key: 31393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard raise DistutilsOptionError( 31493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "Multiple files with name %s" % file) 31593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.install_script_key = '[#%s]' % key 31693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else: 31793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard key = seen[afile] 31893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "DuplicateFile", 31993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(key + version, dir.component, key, None, dir.logical)]) 320ef83ab9db5bda91bd19224c28aa9267f398bb7bfSteven Bethard db.Commit() 321fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cab.commit(db) 322fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 323fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def add_find_python(self): 324fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis """Adds code to the installer to compute the location of Python. 325fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 32693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard Properties PYTHON.MACHINE.X.Y and PYTHON.USER.X.Y will be set from the 32793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard registry for each version of Python. 32893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 32993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard Properties TARGETDIRX.Y will be set from PYTHON.USER.X.Y if defined, 33093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else from PYTHON.MACHINE.X.Y. 33193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 33293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard Properties PYTHONX.Y will be set to TARGETDIRX.Y\\python.exe""" 33393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 33493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard start = 402 33593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for ver in self.versions: 33693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % ver 33793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard machine_reg = "python.machine." + ver 33893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard user_reg = "python.user." + ver 33993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard machine_prop = "PYTHON.MACHINE." + ver 34093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard user_prop = "PYTHON.USER." + ver 34193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard machine_action = "PythonFromMachine" + ver 34293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard user_action = "PythonFromUser" + ver 34393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard exe_action = "PythonExe" + ver 34493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard target_dir_prop = "TARGETDIR" + ver 34593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard exe_prop = "PYTHON" + ver 34683eacca7a601df925a36455119633167a9093cdbMartin v. Löwis if msilib.Win64: 34783eacca7a601df925a36455119633167a9093cdbMartin v. Löwis # type: msidbLocatorTypeRawValue + msidbLocatorType64bit 34883eacca7a601df925a36455119633167a9093cdbMartin v. Löwis Type = 2+16 34983eacca7a601df925a36455119633167a9093cdbMartin v. Löwis else: 35083eacca7a601df925a36455119633167a9093cdbMartin v. Löwis Type = 2 35193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "RegLocator", 35283eacca7a601df925a36455119633167a9093cdbMartin v. Löwis [(machine_reg, 2, install_path, None, Type), 35383eacca7a601df925a36455119633167a9093cdbMartin v. Löwis (user_reg, 1, install_path, None, Type)]) 35493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "AppSearch", 35593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(machine_prop, machine_reg), 35693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (user_prop, user_reg)]) 357fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, "CustomAction", 35893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(machine_action, 51+256, target_dir_prop, "[" + machine_prop + "]"), 35993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (user_action, 51+256, target_dir_prop, "[" + user_prop + "]"), 36093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (exe_action, 51+256, exe_prop, "[" + target_dir_prop + "]\\python.exe"), 36193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ]) 362fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, "InstallExecuteSequence", 36393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(machine_action, machine_prop, start), 36493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (user_action, user_prop, start + 1), 36593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (exe_action, None, start + 2), 36693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ]) 36793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "InstallUISequence", 36893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(machine_action, machine_prop, start), 36993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (user_action, user_prop, start + 1), 37093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard (exe_action, None, start + 2), 37193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ]) 37293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "Condition", 37393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [("Python" + ver, 0, "NOT TARGETDIR" + ver)]) 37493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard start += 4 37593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard assert start < 500 37693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 37793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard def add_scripts(self): 37893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if self.install_script: 37993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard start = 6800 38093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for ver in self.versions + [self.other_version]: 38193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard install_action = "install_script." + ver 38293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard exe_prop = "PYTHON" + ver 38393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "CustomAction", 38493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(install_action, 50, exe_prop, self.install_script_key)]) 38593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard add_data(self.db, "InstallExecuteSequence", 38693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard [(install_action, "&Python%s=3" % ver, start)]) 38793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard start += 1 38893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard # XXX pre-install scripts are currently refused in finalize_options() 38993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard # but if this feature is completed, it will also need to add 39093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard # entries for each version as the above code does 391fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis if self.pre_install_script: 392fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis scriptfn = os.path.join(self.bdist_dir, "preinstall.bat") 393fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis f = open(scriptfn, "w") 394fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # The batch file will be executed with [PYTHON], so that %1 395fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # is the path to the Python interpreter; %0 will be the path 396fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # of the batch file. 397fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # rem =""" 398fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # %1 %0 399fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # exit 400fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # """ 401fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # <actual script> 402fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis f.write('rem ="""\n%1 %0\nexit\n"""\n') 403fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis f.write(open(self.pre_install_script).read()) 404fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis f.close() 405fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, "Binary", 406fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("PreInstall", msilib.Binary(scriptfn)) 407fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ]) 408fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, "CustomAction", 409fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("PreInstall", 2, "PreInstall", None) 410fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ]) 411fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(self.db, "InstallExecuteSequence", 412fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("PreInstall", "NOT Installed", 450)]) 413fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 414fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 415fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def add_ui(self): 416fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis db = self.db 417fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis x = y = 50 418fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis w = 370 419fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis h = 300 420fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis title = "[ProductName] Setup" 421fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 422fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # see "Dialog Style Bits" 423fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis modal = 3 # visible | modal 424fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis modeless = 1 # visible 4253679727939a9d25ccfe057e71e8a4b8be73d47ceTarek Ziadé track_disk_space = 32 426fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 427fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # UI customization properties 428fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(db, "Property", 429fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # See "DefaultUIFont Property" 430fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("DefaultUIFont", "DlgFont8"), 431fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # See "ErrorDialog Style Bit" 432fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("ErrorDialog", "ErrorDlg"), 433fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("Progress1", "Install"), # modified in maintenance type dlg 434fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("Progress2", "installs"), 435fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("MaintenanceForm_Action", "Repair"), 436fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # possible values: ALL, JUSTME 437fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("WhichUsers", "ALL") 438fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ]) 439fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 440fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Fonts, see "TextStyle Table" 441fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(db, "TextStyle", 442fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("DlgFont8", "Tahoma", 9, None, 0), 443fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("DlgFontBold8", "Tahoma", 8, None, 1), #bold 444fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("VerdanaBold10", "Verdana", 10, None, 1), 445fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("VerdanaRed9", "Verdana", 9, 255, 0), 446fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ]) 447fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 448fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table" 449fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Numbers indicate sequence; see sequence.py for how these action integrate 450fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis add_data(db, "InstallUISequence", 451fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140), 452fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141), 453fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # In the user interface, assume all-users installation if privileged. 45493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ("SelectFeaturesDlg", "Not Installed", 1230), 455fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # XXX no support for resume installations yet 456fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), 457fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250), 458fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ("ProgressDlg", None, 1280)]) 459fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 460477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters add_data(db, 'ActionText', text.ActionText) 461477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters add_data(db, 'UIText', text.UIText) 462fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 463fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Standard dialogs: FatalError, UserExit, ExitDialog 464fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title, 465fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Finish", "Finish", "Finish") 466fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal.title("[ProductName] Installer ended prematurely") 467fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal.back("< Back", "Finish", active = 0) 468fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal.cancel("Cancel", "Back", active = 0) 469fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal.text("Description1", 15, 70, 320, 80, 0x30003, 470fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.") 471fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis fatal.text("Description2", 15, 155, 320, 20, 0x30003, 472fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Click the Finish button to exit the Installer.") 473fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=fatal.next("Finish", "Cancel", name="Finish") 474fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Exit") 475fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 476fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title, 477fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Finish", "Finish", "Finish") 478fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit.title("[ProductName] Installer was interrupted") 479fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit.back("< Back", "Finish", active = 0) 480fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit.cancel("Cancel", "Back", active = 0) 481fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit.text("Description1", 15, 70, 320, 80, 0x30003, 482fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "[ProductName] setup was interrupted. Your system has not been modified. " 483fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "To install this program at a later time, please run the installation again.") 484fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis user_exit.text("Description2", 15, 155, 320, 20, 0x30003, 485fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Click the Finish button to exit the Installer.") 486fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = user_exit.next("Finish", "Cancel", name="Finish") 487fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Exit") 488fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 489fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title, 490fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Finish", "Finish", "Finish") 491fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis exit_dialog.title("Completing the [ProductName] Installer") 492fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis exit_dialog.back("< Back", "Finish", active = 0) 493fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis exit_dialog.cancel("Cancel", "Back", active = 0) 494fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis exit_dialog.text("Description", 15, 235, 320, 20, 0x30003, 495fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Click the Finish button to exit the Installer.") 496fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = exit_dialog.next("Finish", "Cancel", name="Finish") 497fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Return") 498fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 499fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 500fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Required dialog: FilesInUse, ErrorDlg 501fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis inuse = PyDialog(db, "FilesInUse", 502fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis x, y, w, h, 503fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 19, # KeepModeless|Modal|Visible 504fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis title, 505fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Retry", "Retry", "Retry", bitmap=False) 506fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis inuse.text("Title", 15, 6, 200, 15, 0x30003, 507fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis r"{\DlgFontBold8}Files in Use") 508fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis inuse.text("Description", 20, 23, 280, 20, 0x30003, 509fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Some files that need to be updated are currently in use.") 510fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis inuse.text("Text", 20, 55, 330, 50, 3, 511fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.") 512fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess", 513fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis None, None, None) 514fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=inuse.back("Exit", "Ignore", name="Exit") 515fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Exit") 516fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=inuse.next("Ignore", "Retry", name="Ignore") 517fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Ignore") 518fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=inuse.cancel("Retry", "Exit", name="Retry") 519fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog","Retry") 520fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 521fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # See "Error Dialog". See "ICE20" for the required names of the controls. 522fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error = Dialog(db, "ErrorDlg", 523fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 50, 10, 330, 101, 524fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 65543, # Error|Minimize|Modal|Visible 525fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis title, 526fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "ErrorText", None, None) 527fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.text("ErrorText", 50,9,280,48,3, "") 528fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) 529fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo") 530fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes") 531fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort") 532fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel") 533fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore") 534fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk") 535fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry") 536fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 537fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 538fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Global "Query Cancel" dialog 539fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, 540fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "No", "No", "No") 541fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cancel.text("Text", 48, 15, 194, 30, 3, 542fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Are you sure you want to cancel [ProductName] installation?") 543fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, 544fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # "py.ico", None, None) 545fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No") 546fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Exit") 547fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 548fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes") 549fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Return") 550fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 551fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 552fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Global "Wait for costing" dialog 553fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title, 554fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Return", "Return", "Return") 555fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis costing.text("Text", 48, 15, 194, 30, 3, 556fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Please wait while the installer finishes determining your disk space requirements.") 557fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None) 558fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Exit") 559fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 560fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 561fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Preparation dialog: no user input except cancellation 562fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title, 563fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Cancel", "Cancel", "Cancel") 564fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis prep.text("Description", 15, 70, 320, 40, 0x30003, 565fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Please wait while the Installer prepares to guide you through the installation.") 566fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis prep.title("Welcome to the [ProductName] Installer") 567fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...") 568fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.mapping("ActionText", "Text") 569fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None) 570fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.mapping("ActionData", "Text") 571fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis prep.back("Back", None, active=0) 572fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis prep.next("Next", None, active=0) 573fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=prep.cancel("Cancel", None) 574fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("SpawnDialog", "CancelDlg") 575fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 576fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 57793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard # Feature (Python directory) selection 57893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title, 579fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Next", "Next", "Cancel") 58093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard seldlg.title("Select Python Installations") 581fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 58293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard seldlg.text("Hint", 15, 30, 300, 20, 3, 58393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "Select the Python locations where %s should be installed." 58493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard % self.distribution.get_fullname()) 585fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 586fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis seldlg.back("< Back", None, active=0) 587fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = seldlg.next("Next >", "Cancel") 58893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard order = 1 58993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.event("[TARGETDIR]", "[SourceDir]", ordering=order) 59093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard for version in self.versions + [self.other_version]: 59193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard order += 1 59293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.event("[TARGETDIR]", "[TARGETDIR%s]" % version, 59393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "FEATURE_SELECTED AND &Python%s=3" % version, 59493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ordering=order) 59593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1) 59693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.event("EndDialog", "Return", ordering=order + 2) 59793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c = seldlg.cancel("Cancel", "Features") 598fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("SpawnDialog", "CancelDlg") 599fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 60093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3, 60193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "FEATURE", None, "PathEdit", None) 60293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.event("[FEATURE_SELECTED]", "1") 60393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard ver = self.other_version 60493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver 60593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver 60693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 60793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c = seldlg.text("Other", 15, 200, 300, 15, 3, 60893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "Provide an alternate Python location") 60993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Enable", install_other_cond) 61093f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Show", install_other_cond) 61193f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Disable", dont_install_other_cond) 61293f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Hide", dont_install_other_cond) 61393f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard 61493f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1, 61593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard "TARGETDIR" + ver, None, "Next", None) 61693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Enable", install_other_cond) 61793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Show", install_other_cond) 61893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Disable", dont_install_other_cond) 61993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard c.condition("Hide", dont_install_other_cond) 620fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 621fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 622fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Disk cost 623fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title, 624fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "OK", "OK", "OK", bitmap=False) 625fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost.text("Title", 15, 6, 200, 15, 0x30003, 62644b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray r"{\DlgFontBold8}Disk Space Requirements") 627fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost.text("Description", 20, 20, 280, 20, 0x30003, 628fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "The disk space required for the installation of the selected features.") 629fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost.text("Text", 20, 53, 330, 60, 3, 630fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "The highlighted volumes (if any) do not have enough disk space " 631fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "available for the currently selected features. You can either " 632fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "remove some files from the highlighted volumes, or choose to " 633fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "install less features onto local drive(s), or select different " 634fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "destination drive(s).") 635fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223, 636fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis None, "{120}{70}{70}{70}{70}", None, None) 637fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return") 638fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 639fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 640fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # WhichUsers Dialog. Only available on NT, and for privileged users. 641fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # This must be run before FindRelatedProducts, because that will 642fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # take into account whether the previous installation was per-user 643fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # or per-machine. We currently don't support going back to this 644fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # dialog after "Next" was selected; to support this, we would need to 645fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # find how to reset the ALLUSERS property, and how to re-run 646fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # FindRelatedProducts. 647fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # On Windows9x, the ALLUSERS property is ignored on the command line 648fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # and in the Property table, but installer fails according to the documentation 649fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # if a dialog attempts to set ALLUSERS. 650fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title, 651fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "AdminInstall", "Next", "Cancel") 652fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis whichusers.title("Select whether to install [ProductName] for all users of this computer.") 653fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # A radio group with two options: allusers, justme 654fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3, 655fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "WhichUsers", "", "Next") 656fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g.add("ALL", 0, 5, 150, 20, "Install for all users") 657fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g.add("JUSTME", 0, 25, 150, 20, "Install just for me") 658fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 659fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis whichusers.back("Back", None, active=0) 660fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 661fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = whichusers.next("Next >", "Cancel") 662fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1) 663477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters c.event("EndDialog", "Return", ordering = 2) 664fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 665fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c = whichusers.cancel("Cancel", "AdminInstall") 666fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("SpawnDialog", "CancelDlg") 667fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 668fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ##################################################################### 669fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Installation Progress dialog (modeless) 670fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title, 671fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Cancel", "Cancel", "Cancel", bitmap=False) 672fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.text("Title", 20, 15, 200, 15, 0x30003, 67344b548dda872c0d4f30afd6b44fd74b053a55ad8R David Murray r"{\DlgFontBold8}[Progress1] [ProductName]") 674fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.text("Text", 35, 65, 300, 30, 3, 675fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Please wait while the Installer [Progress2] [ProductName]. " 676fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "This may take several minutes.") 677fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:") 678fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 679fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...") 680fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.mapping("ActionText", "Text") 681fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 682fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #c=progress.text("ActionData", 35, 140, 300, 20, 3, None) 683fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #c.mapping("ActionData", "Text") 684fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 685fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537, 686fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis None, "Progress done", None, None) 687fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.mapping("SetProgress", "Progress") 688fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 689fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.back("< Back", "Next", active=False) 690fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.next("Next >", "Cancel", active=False) 691fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg") 692fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 693fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis ################################################################### 694fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Maintenance type: repair/uninstall 695fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title, 696fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Next", "Next", "Cancel") 697fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis maint.title("Welcome to the [ProductName] Setup Wizard") 698fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis maint.text("BodyText", 15, 63, 330, 42, 3, 699fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "Select whether you want to repair or remove [ProductName].") 700fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3, 701fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis "MaintenanceForm_Action", "", "Next") 702fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]") 703fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]") 704fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]") 705fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 706fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis maint.back("< Back", None, active=False) 707fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c=maint.next("Finish", "Cancel") 708fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Change installation: Change progress dialog to "Change", then ask 709fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # for feature selection 710fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1) 711fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2) 712fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 713fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Reinstall: Change progress dialog to "Repair", then invoke reinstall 714fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Also set list of reinstalled features to "ALL" 715fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5) 716fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6) 717fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7) 718fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8) 719fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 720fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Uninstall: Change progress to "Remove", then invoke uninstall 721fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Also set list of removed features to "ALL" 722fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11) 723fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12) 724fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13) 725fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14) 726fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 727fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Close dialog when maintenance action scheduled 728fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20) 729fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21) 730fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 731fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg") 732fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis 733fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis def get_installer_filename(self, fullname): 734fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis # Factored out to allow overriding in subclasses 73593f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard if self.target_version: 73693f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name, 73793f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard self.target_version) 73893f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard else: 73993f65a177b36396dddd1e2938cc037288a7eb400Steven Bethard base_name = "%s.%s.msi" % (fullname, self.plat_name) 7405e69685999c0f44af3536ac71a2a59e70b7ea185Christian Heimes installer_name = os.path.join(self.dist_dir, base_name) 741fbab90e95bf6403269d702e8e85ef3a6eceafbb0Martin v. Löwis return installer_name 742