예제 #1
0
 def add_find_python(self):
     """Adds code to the installer to compute the location of Python.
     Properties PYTHON.MACHINE, PYTHON.USER, PYTHONDIR and PYTHON will be set
     in both the execute and UI sequences; PYTHONDIR will be set from
     PYTHON.USER if defined, else from PYTHON.MACHINE.
     PYTHON is PYTHONDIR\python.exe"""
     install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % self.target_version
     add_data(self.db, "RegLocator",
             [("python.machine", 2, install_path, None, 2),
              ("python.user", 1, install_path, None, 2)])
     add_data(self.db, "AppSearch",
             [("PYTHON.MACHINE", "python.machine"),
              ("PYTHON.USER", "python.user")])
     add_data(self.db, "CustomAction",
             [("PythonFromMachine", 51+256, "PYTHONDIR", "[PYTHON.MACHINE]"),
              ("PythonFromUser", 51+256, "PYTHONDIR", "[PYTHON.USER]"),
              ("PythonExe", 51+256, "PYTHON", "[PYTHONDIR]\\python.exe"),
              ("InitialTargetDir", 51+256, "TARGETDIR", "[PYTHONDIR]")])
     add_data(self.db, "InstallExecuteSequence",
             [("PythonFromMachine", "PYTHON.MACHINE", 401),
              ("PythonFromUser", "PYTHON.USER", 402),
              ("PythonExe", None, 403),
              ("InitialTargetDir", 'TARGETDIR=""', 404),
             ])
     add_data(self.db, "InstallUISequence",
             [("PythonFromMachine", "PYTHON.MACHINE", 401),
              ("PythonFromUser", "PYTHON.USER", 402),
              ("PythonExe", None, 403),
              ("InitialTargetDir", 'TARGETDIR=""', 404),
             ])
예제 #2
0
 def add_scripts(self):
     if self.install_script:
         start = 6800
         for ver in self.versions + [self.other_version]:
             install_action = "install_script." + ver
             exe_prop = "PYTHON" + ver
             add_data(
                 self.db, "CustomAction",
                 [(install_action, 50, exe_prop, self.install_script_key)])
             add_data(self.db, "InstallExecuteSequence",
                      [(install_action, "&Python%s=3" % ver, start)])
             start += 1
     # XXX pre-install scripts are currently refused in finalize_options()
     #     but if this feature is completed, it will also need to add
     #     entries for each version as the above code does
     if self.pre_install_script:
         scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
         with open(scriptfn, "w") as f:
             # The batch file will be executed with [PYTHON], so that %1
             # is the path to the Python interpreter; %0 will be the path
             # of the batch file.
             # rem ="""
             # %1 %0
             # exit
             # """
             # <actual script>
             f.write('rem ="""\n%1 %0\nexit\n"""\n')
             with open(self.pre_install_script) as fin:
                 f.write(fin.read())
         add_data(self.db, "Binary",
                  [("PreInstall", msilib.Binary(scriptfn))])
         add_data(self.db, "CustomAction",
                  [("PreInstall", 2, "PreInstall", None)])
         add_data(self.db, "InstallExecuteSequence",
                  [("PreInstall", "NOT Installed", 450)])
예제 #3
0
 def add_scripts(self):
     if self.install_script:
         add_data(self.db, "CustomAction",
                 [("install_script", 50, "PYTHON", self.install_script_key)])
         add_data(self.db, "InstallExecuteSequence",
                 [("install_script", "NOT Installed", 6800)])
     if self.pre_install_script:
         scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
         f = open(scriptfn, "w")
         # The batch file will be executed with [PYTHON], so that %1
         # is the path to the Python interpreter; %0 will be the path
         # of the batch file.
         # rem ="""
         # %1 %0
         # exit
         # """
         # <actual script>
         f.write('rem ="""\n%1 %0\nexit\n"""\n')
         f.write(open(self.pre_install_script).read())
         f.close()
         add_data(self.db, "Binary",
             [("PreInstall", msilib.Binary(scriptfn))
             ])
         add_data(self.db, "CustomAction",
             [("PreInstall", 2, "PreInstall", None)
             ])
         add_data(self.db, "InstallExecuteSequence",
                 [("PreInstall", "NOT Installed", 450)])
    def add_scripts(self):
        if self.install_script:
            start = 6800
            for ver in self.versions + [self.other_version]:
                install_action = 'install_script.' + ver
                exe_prop = 'PYTHON' + ver
                add_data(
                    self.db, 'CustomAction',
                    [(install_action, 50, exe_prop, self.install_script_key)])
                add_data(self.db, 'InstallExecuteSequence',
                         [(install_action, '&Python%s=3' % ver, start)])
                start += 1

        if self.pre_install_script:
            scriptfn = os.path.join(self.bdist_dir, 'preinstall.bat')
            f = open(scriptfn, 'w')
            f.write('rem ="""\n%1 %0\nexit\n"""\n')
            f.write(open(self.pre_install_script).read())
            f.close()
            add_data(self.db, 'Binary',
                     [('PreInstall', msilib.Binary(scriptfn))])
            add_data(self.db, 'CustomAction',
                     [('PreInstall', 2, 'PreInstall', None)])
            add_data(self.db, 'InstallExecuteSequence',
                     [('PreInstall', 'NOT Installed', 450)])
        return None
예제 #5
0
 def add_find_python(self):
     """Adds code to the installer to compute the location of Python.
     Properties PYTHON.MACHINE, PYTHON.USER, PYTHONDIR and PYTHON will be set
     in both the execute and UI sequences; PYTHONDIR will be set from
     PYTHON.USER if defined, else from PYTHON.MACHINE.
     PYTHON is PYTHONDIR\python.exe"""
     install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % self.target_version
     if msilib.Win64:
         # type: msidbLocatorTypeRawValue + msidbLocatorType64bit
         Type = 2 + 16
     else:
         Type = 2
     add_data(self.db, "RegLocator",
              [("python.machine", 2, install_path, None, Type),
               ("python.user", 1, install_path, None, Type)])
     add_data(self.db, "AppSearch", [("PYTHON.MACHINE", "python.machine"),
                                     ("PYTHON.USER", "python.user")])
     add_data(
         self.db, "CustomAction",
         [("PythonFromMachine", 51 + 256, "PYTHONDIR", "[PYTHON.MACHINE]"),
          ("PythonFromUser", 51 + 256, "PYTHONDIR", "[PYTHON.USER]"),
          ("PythonExe", 51 + 256, "PYTHON", "[PYTHONDIR]\\python.exe"),
          ("InitialTargetDir", 51 + 256, "TARGETDIR", "[PYTHONDIR]")])
     add_data(self.db, "InstallExecuteSequence", [
         ("PythonFromMachine", "PYTHON.MACHINE", 401),
         ("PythonFromUser", "PYTHON.USER", 402),
         ("PythonExe", None, 403),
         ("InitialTargetDir", 'TARGETDIR=""', 404),
     ])
     add_data(self.db, "InstallUISequence", [
         ("PythonFromMachine", "PYTHON.MACHINE", 401),
         ("PythonFromUser", "PYTHON.USER", 402),
         ("PythonExe", None, 403),
         ("InitialTargetDir", 'TARGETDIR=""', 404),
     ])
예제 #6
0
 def add_scripts(self):
     if self.install_script:
         add_data(
             self.db, "CustomAction",
             [("install_script", 50, "PYTHON", self.install_script_key)])
         add_data(self.db, "InstallExecuteSequence",
                  [("install_script", "NOT Installed", 6800)])
     if self.pre_install_script:
         scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
         f = open(scriptfn, "w")
         # The batch file will be executed with [PYTHON], so that %1
         # is the path to the Python interpreter; %0 will be the path
         # of the batch file.
         # rem ="""
         # %1 %0
         # exit
         # """
         # <actual script>
         f.write('rem ="""\n%1 %0\nexit\n"""\n')
         f.write(open(self.pre_install_script).read())
         f.close()
         add_data(self.db, "Binary",
                  [("PreInstall", msilib.Binary(scriptfn))])
         add_data(self.db, "CustomAction",
                  [("PreInstall", 2, "PreInstall", None)])
         add_data(self.db, "InstallExecuteSequence",
                  [("PreInstall", "NOT Installed", 450)])
예제 #7
0
파일: windist.py 프로젝트: ycj/cx_Freeze
    def add_properties(self):
        metadata = self.distribution.metadata
        props = [('DistVersion', metadata.get_version()),
                 ('DefaultUIFont', 'DlgFont8'), ('ErrorDialog', 'ErrorDlg'),
                 ('Progress1', 'Install'), ('Progress2', 'installs'),
                 ('MaintenanceForm_Action', 'Repair'), ('ALLUSERS', '2')]

        if not self.all_users:
            props.append(('MSIINSTALLPERUSER', '1'))
        email = metadata.author_email or metadata.maintainer_email
        if email:
            props.append(("ARPCONTACT", email))
        if metadata.url:
            props.append(("ARPURLINFOABOUT", metadata.url))
        if self.upgrade_code is not None:
            if not is_valid_GUID(self.upgrade_code):
                raise ValueError("upgrade-code must be in valid GUID format")
            props.append(("UpgradeCode", self.upgrade_code.upper()))
        if self.install_icon:
            props.append(('ARPPRODUCTICON', 'InstallIcon'))
        msilib.add_data(self.db, 'Property', props)
        if self.install_icon:
            msilib.add_data(
                self.db, "Icon",
                [("InstallIcon", msilib.Binary(self.install_icon))])
    def add_files(self):
        db = self.db
        cab = msilib.CAB('distfiles')
        rootdir = os.path.abspath(self.bdist_dir)
        root = Directory(db, cab, None, rootdir, 'TARGETDIR', 'SourceDir')
        f = Feature(db,
                    'Python',
                    'Python',
                    'Everything',
                    0,
                    1,
                    directory='TARGETDIR')
        items = [(f, root, '')]
        for version in self.versions + [self.other_version]:
            target = 'TARGETDIR' + version
            name = default = 'Python' + version
            desc = 'Everything'
            if version is self.other_version:
                title = 'Python from another location'
                level = 2
            else:
                title = 'Python %s from registry' % version
                level = 1
            f = Feature(db, name, title, desc, 1, level, directory=target)
            dir = Directory(db, cab, root, rootdir, target, default)
            items.append((f, dir, version))

        db.Commit()
        seen = {}
        for feature, dir, version in items:
            todo = [dir]
            while todo:
                dir = todo.pop()
                for file in os.listdir(dir.absolute):
                    afile = os.path.join(dir.absolute, file)
                    if os.path.isdir(afile):
                        short = '%s|%s' % (dir.make_short(file), file)
                        default = file + version
                        newdir = Directory(db, cab, dir, file, default, short)
                        todo.append(newdir)
                    else:
                        if not dir.component:
                            dir.start_component(dir.logical, feature, 0)
                        if afile not in seen:
                            key = seen[afile] = dir.add_file(file)
                            if file == self.install_script:
                                if self.install_script_key:
                                    raise DistutilsOptionError(
                                        'Multiple files with name %s' % file)
                                self.install_script_key = '[#%s]' % key
                        else:
                            key = seen[afile]
                            add_data(self.db, 'DuplicateFile',
                                     [(key + version, dir.component, key, None,
                                       dir.logical)])

            db.Commit()

        cab.commit(db)
        return
예제 #9
0
    def add_properties(self):
        metadata = self.distribution.metadata
        props = [
            ("DistVersion", metadata.get_version()),
            ("DefaultUIFont", "DlgFont8"),
            ("ErrorDialog", "ErrorDlg"),
            ("Progress1", "Install"),
            ("Progress2", "installs"),
            ("MaintenanceForm_Action", "Repair"),
            ("ALLUSERS", "2"),
        ]

        if not self.all_users:
            props.append(("MSIINSTALLPERUSER", "1"))
        email = metadata.author_email or metadata.maintainer_email
        if email:
            props.append(("ARPCONTACT", email))
        if metadata.url:
            props.append(("ARPURLINFOABOUT", metadata.url))
        if self.upgrade_code is not None:
            if not is_valid_GUID(self.upgrade_code):
                raise ValueError("upgrade-code must be in valid GUID format")
            props.append(("UpgradeCode", self.upgrade_code.upper()))
        if self.install_icon:
            props.append(("ARPPRODUCTICON", "InstallIcon"))
        msilib.add_data(self.db, "Property", props)
        if self.install_icon:
            msilib.add_data(
                self.db,
                "Icon",
                [("InstallIcon", msilib.Binary(self.install_icon))],
            )
예제 #10
0
        def add_exit_dialog(self):
            # Add the license screen
            if self.get_licence() is not None:
                self.add_licence_dialog()

            # Allow to customize the MSI
            if hasattr(self.attribs, 'customize_msi'):
                self.attribs.customize_msi(self.db)

            # Add the product icon in control panel Install/Remove softwares
            icon_file = os.path.join(self.attribs.get_icons_home(),
                                     self.attribs.get_win_icon())
            if os.path.exists(icon_file):
                msilib.add_data(self.db, 'Property', [
                    ('ARPPRODUCTICON', 'InstallIcon'),
                ])
                msilib.add_data(self.db, 'Icon', [(
                    'InstallIcon', msilib.Binary(icon_file))])

            # Copy/paste from parent's method
            dialog = distutils.command.bdist_msi.PyDialog(
                self.db, 'ExitDialog',
                self.x, self.y, self.width, self.height, self.modal,
                self.title, 'Finish', 'Finish', 'Finish')
            dialog.title('Completing the [ProductName]')
            dialog.back('< Back', 'Finish', active=False)
            dialog.cancel('Cancel', 'Back', active=False)
            dialog.text(
                'Description', 15, 235, 320, 20, 0x30003,
                'Click the Finish button to exit the installer.')
            button = dialog.next('Finish', 'Cancel', name='Finish')
            button.event('EndDialog', 'Return')

            """
 def add_upgrade_config(self, sversion):
     if self.upgrade_code is not None:
         msilib.add_data(self.db, 'Upgrade',
                         [(self.upgrade_code, None, sversion, None, 513,
                           None, "REMOVEOLDVERSION"),
                          (self.upgrade_code, sversion, None, None, 257,
                           None, "REMOVENEWVERSION")])
예제 #12
0
		def control_service(service):
			start_on = service.control.get('start_on', 0)
			stop_on = service.control.get('stop_on', 0)
			remove_on = service.control.get('remove_on', 0)

			if not (start_on or stop_on or remove_on):
				log.warn('skipping controller for %s service, no events specified', service.name)
			else:
				log.info('adding controller for %s service', service.name)

			comp_id = get_service_comp(service)

			event = (
			(Service._msidbServiceControlEventStart if start_on & Service.INSTALL else 0) |
			(Service._msidbServiceControlEventStop if stop_on & Service.INSTALL else 0) |
			(Service._msidbServiceControlEventDelete if remove_on & Service.INSTALL else 0) |
			(Service._msidbServiceControlEventUninstallStart if start_on & Service.UNINSTALL else 0) |
			(Service._msidbServiceControlEventUninstallStop if stop_on & Service.UNINSTALL else 0) |
			(Service._msidbServiceControlEventUninstallDelete if remove_on & Service.UNINSTALL else 0))

			msilib.add_data(self.db, 'ServiceControl', [(
				comp_id,  # ServiceControl
				service.name,  # Name
				event,  # Event
				'~'.join(service.control.get('args', [])),  # Arguments
				1 if service.control.get('wait', True) else 0,  # Wait
				comp_id  # Component_
			)])
예제 #13
0
        def add_exit_dialog(self):
            # Add the license screen
            if self.get_licence() is not None:
                self.add_licence_dialog()

            # Allow to customize the MSI
            if hasattr(self.attribs, 'customize_msi'):
                self.attribs.customize_msi(self.db)

            # Add the product icon in control panel Install/Remove softwares
            icon_file = os.path.join(self.attribs.get_icons_home(),
                                     self.attribs.get_win_icon())
            if os.path.exists(icon_file):
                msilib.add_data(self.db, 'Property', [
                    ('ARPPRODUCTICON', 'InstallIcon'),
                ])
                msilib.add_data(self.db, 'Icon',
                                [('InstallIcon', msilib.Binary(icon_file))])

            # Copy/paste from parent's method
            dialog = distutils.command.bdist_msi.PyDialog(
                self.db, 'ExitDialog', self.x, self.y, self.width, self.height,
                self.modal, self.title, 'Finish', 'Finish', 'Finish')
            dialog.title('Completing the [ProductName]')
            dialog.back('< Back', 'Finish', active=False)
            dialog.cancel('Cancel', 'Back', active=False)
            dialog.text('Description', 15, 235, 320, 20, 0x30003,
                        'Click the Finish button to exit the installer.')
            button = dialog.next('Finish', 'Cancel', name='Finish')
            button.event('EndDialog', 'Return')
            """
예제 #14
0
 def add_scripts(self):
     if self.install_script:
         start = 6800
         for ver in self.versions + [self.other_version]:
             install_action = "install_script." + ver
             exe_prop = "PYTHON" + ver
             add_data(self.db, "CustomAction", [(install_action, 50, exe_prop, self.install_script_key)])
             add_data(self.db, "InstallExecuteSequence", [(install_action, "&Python%s=3" % ver, start)])
             start += 1
     # XXX pre-install scripts are currently refused in finalize_options()
     #     but if this feature is completed, it will also need to add
     #     entries for each version as the above code does
     if self.pre_install_script:
         scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
         f = open(scriptfn, "w")
         # The batch file will be executed with [PYTHON], so that %1
         # is the path to the Python interpreter; %0 will be the path
         # of the batch file.
         # rem ="""
         # %1 %0
         # exit
         # """
         # <actual script>
         f.write('rem ="""\n%1 %0\nexit\n"""\n')
         f.write(open(self.pre_install_script).read())
         f.close()
         add_data(self.db, "Binary", [("PreInstall", msilib.Binary(scriptfn))])
         add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", None)])
         add_data(self.db, "InstallExecuteSequence", [("PreInstall", "NOT Installed", 450)])
예제 #15
0
 def add_config(self, fullname):
     # Hardwired b/c there is only one Executable() above
     index = 0
     baseName = os.path.basename(self.distribution.executables[index].targetName)
     # http://stackoverflow.com/questions/24195311/how-to-set-shortcut-working-directory-in-cx-freeze-msi-bundle
     msilib.add_data(
         self.db,
         "Shortcut",
         [
             (
                 "S_APP_%s" % index,
                 "DesktopFolder",
                 "QWeb",
                 "TARGETDIR",
                 "[TARGETDIR]%s" % baseName,
                 None,
                 None,
                 None,
                 None,
                 None,
                 None,
                 "TARGETDIR",
             )
         ],
     )
     cx_Freeze.bdist_msi.add_config(self, fullname)
예제 #16
0
 def add_text_styles(self):
     msilib.add_data(self.db, 'TextStyle',
             [("DlgFont8", "Tahoma", 9, None, 0),
              ("DlgFontBold8", "Tahoma", 8, None, 1),
              ("VerdanaBold10", "Verdana", 10, None, 1),
              ("VerdanaRed9", "Verdana", 9, 255, 0)
             ])
예제 #17
0
def merge(msi, feature, rootdir, modules):
    cab_and_filecount = []
    # Step 1: Merge databases, extract cabfiles
    m = msilib.MakeMerge2()
    m.OpenLog("merge.log")
    print "Opened Log"
    m.OpenDatabase(msi)
    print "Opened DB"
    for module in modules:
        print module
        m.OpenModule(module, 0)
        print "Opened Module", module
        m.Merge(feature, rootdir)
        print "Errors:"
        for e in m.Errors:
            print e.Type, e.ModuleTable, e.DatabaseTable
            print "   Modkeys:",
            for s in e.ModuleKeys:
                print s,
            print
            print "   DBKeys:",
            for s in e.DatabaseKeys:
                print s,
            print
        cabname = tempfile.mktemp(suffix=".cab")
        m.ExtractCAB(cabname)
        cab_and_filecount.append((cabname, len(m.ModuleFiles)))
        m.CloseModule()
    m.CloseDatabase(True)
    m.CloseLog()

    # Step 2: Add CAB files
    i = msilib.MakeInstaller()
    db = i.OpenDatabase(msi, win32com.client.constants.msiOpenDatabaseModeTransact)

    v = db.OpenView("SELECT LastSequence FROM Media")
    v.Execute(None)
    maxmedia = -1
    while 1:
        r = v.Fetch()
        if not r:
            break
        seq = r.IntegerData(1)
        if seq > maxmedia:
            maxmedia = seq
    print "Start of Media", maxmedia

    for cabname, count in cab_and_filecount:
        stream = "merged%d" % maxmedia
        msilib.add_data(db, "Media", [(maxmedia + 1, maxmedia + count, None, "#" + stream, None, None)])
        msilib.add_stream(db, stream, cabname)
        os.unlink(cabname)
        maxmedia += count
    # The merge module sets ALLUSERS to 1 in the property table.
    # This is undesired; delete that
    v = db.OpenView("DELETE FROM Property WHERE Property='ALLUSERS'")
    v.Execute(None)
    v.Close()
    db.Commit()
예제 #18
0
	def run(self):
		if not (os.path.isdir(self.bdist_dir) and self.skip_build):
			self.run_command('py2exe')

		fullname = self.distribution.get_fullname()
		installer_name = self.get_installer_filename(fullname)
		installer_name = os.path.abspath(installer_name)

		if os.path.exists(installer_name):
			os.unlink(installer_name)

		metadata = self.distribution.metadata
		author = metadata.author

		if not author:
			author = metadata.maintainer
		if not author:
			author = 'UNKNOWN'

		version = metadata.get_version()
		sversion = '%d.%d.%d' % StrictVersion(version).version
		product_name = self.distribution.get_name()

		log.info('creating MSI package %s', installer_name)

		self.db = msilib.init_database(installer_name, schema,
				product_name, self.product_code or msilib.gen_uuid(), sversion, author)

		msilib.add_tables(self.db, sequence)

		props = []

		if self.upgrade_code:
			props.extend([
				('UpgradeCode', self.upgrade_code),
				('SecureCustomProperties', 'REPLACE')
			])

			msilib.add_data(self.db, 'Upgrade', [(
				self.upgrade_code,  # UpgradeCode
				None,  # VersionMin, detect all
				sversion,  # VersionMax
				None,  # Language
				0,  # Attributes
				None,  # Remove, REMOVE=ALL
				'REPLACE'  # ActionProperty
			)])

		if props:
			msilib.add_data(self.db, 'Property', props)

		self.add_files()
		self.add_services()

		self.db.Commit()

		if not self.keep_temp:
			remove_tree(self.bdist_dir, dry_run=self.dry_run)
			remove_tree(self.get_finalized_command('build').build_base)
예제 #19
0
 def customize_msi(self, db):
     import msilib
     # Add the possibility to bind an engine with MSI
     msilib.add_data(db, "CustomAction", [("NuxeoDriveBinder", 82,
                     self.get_win_targetName(),
                     "bind-server --password \"[TARGETPASSWORD]\" --local-folder \"[TARGETDRIVEFOLDER]\" [TARGETUSERNAME] [TARGETURL]")])
     msilib.add_data(db, "InstallExecuteSequence", [("NuxeoDriveBinder",
                           'NOT (TARGETUSERNAME="" OR TARGETURL="")', -1)])
예제 #20
0
 def add_registry(self):
     # File extensions, associated with the REGISTRY component
     # msidbComponentAttributesRegistryKeyPath = 4
     add_data(self.db, "Component", [("REGISTRY", msilib.gen_uuid(),
                                      "TARGETDIR", 4, None, "InstallPath")])
     add_data(self.db, "FeatureComponents",
              [(default_feature.id, "REGISTRY")])
     self.db.Commit()
예제 #21
0
 def run(self):
     bdist_msi.run(self)
     add_data(
         self.db, 'Shortcut',
         [('DesktopShortcut', 'DesktopFolder', 'idlespork', 'Scripts',
           r'[TARGETDIR]\pythonw.exe', r'"[Scripts]\idlespork"', None,
           None, None, None, None, None)])
     self.db.Commit()
예제 #22
0
 def add_upgrade_config(self, sversion):
     if self.upgrade_code is not None:
         msilib.add_data(self.db, 'Upgrade',
                 [(self.upgrade_code, None, sversion, None, 513, None,
                         "REMOVEOLDVERSION"),
                  (self.upgrade_code, sversion, None, None, 257, None,
                         "REMOVENEWVERSION")
                 ])
예제 #23
0
def create_msi_installer(package,
                         run_node,
                         msi_root_node,
                         installer_name=None,
                         output_dir="dist"):
    meta = PackageMetadata.from_package(package)

    string_version = "%d.%d.%d" % (meta.version_major, meta.version_minor,
                                   meta.version_micro)

    fullname = "%s-%s" % (package.name, string_version)
    if installer_name is None:
        installer_name = "%s-%s.msi" % (package.name, string_version)
    parent_node = run_node.make_node(output_dir)
    if parent_node is None:
        raise IOError()
    installer_node = parent_node.make_node(installer_name)
    installer_name = installer_node.abspath()
    installer_node.parent.mkdir()

    author = meta.author

    short_version = sysconfig.get_python_version()

    has_ext_modules = True
    if has_ext_modules:
        target_version = short_version
    else:
        target_version = None

    if target_version:
        product_name = "Python %s %s" % (target_version, meta.fullname)
    else:
        product_name = "Python %s" % meta.fullname

    if target_version:
        versions = [target_version]
    else:
        versions = list(ALL_VERSIONS)

    db = msilib.init_database(installer_name, schema, product_name,
                              msilib.gen_uuid(), string_version, author)
    msilib.add_tables(db, sequence)

    props = [('DistVersion', meta.version)]
    email = meta.author_email or meta.maintainer_email
    if email:
        props.append(("ARPCONTACT", email))
    if meta.url:
        props.append(("ARPURLINFOABOUT", meta.url))
    if props:
        add_data(db, 'Property', props)

    add_find_python(db, versions)
    add_files(db, msi_root_node, versions, OTHER_VERSION)
    add_scripts(db)
    add_ui(db, fullname, versions, OTHER_VERSION)
    db.Commit()
예제 #24
0
    def generate_MSI(self):
        shutil.copy(self.template, self.msifile.path)
        #1 Add exe and ini file to cab
        filelist = [(self.exefile.path, "ExeFile"),
                    (self.inifile.path, "IniFile")]
        cabfile = os.path.join(self.tempdir, "files.cab")
        msilib.FCICreate(cabfile, filelist)

        #2 Open the MSI database
        #database = msilib.init_database(self.msifile.path, msilib.schema, self.msifile.name,  self.productcode, self.productversion, self.manufacturer)
        #print self.msifile.path
        #msilib.add_tables(database, msilib.schema)
        database = msilib.OpenDatabase(self.msifile.path,
                                       msilib.MSIDBOPEN_DIRECT)
        msilib.add_stream(database, "Wpkg_GP.cab", cabfile)

        # Update Product Code
        summaryinformation = database.GetSummaryInformation(1)
        summaryinformation.SetProperty(msilib.PID_REVNUMBER, self.package_GUID)
        summaryinformation.Persist()

        # Add information to Media
        # DiskId | LastSequence | DiskPrompt | Cabinet | VolumeLabel | Source
        table = "Media"
        records = [(1, 2, None, "#Wpkg_GP.cab", None, None)]
        msilib.add_data(database, table, records)

        #CAB = msilib.CAB("Wpkg_GP.cab")
        #CAB.append(self.exefile.path, "ExeFile", "ExeFile")
        #CAB.append(self.inifile.path, "IniFile", "IniFile")
        #CAB.commit(database)

        # Add information to File
        # File | Component_ | FileName | FileSize| Version | Language | Attributes | Sequence
        table = "File"
        records = [("ExeFile", "Installer", self.exefile.name,
                    self.exefile.size, None, None, 512, 1),
                   ("IniFile", "Installer", self.inifile.name,
                    self.inifile.size, None, None, 512, 2)]
        msilib.add_data(database, table, records)

        # Add information to CustomAction
        # Action | Type | Source | Target
        # For Type, see: http://msdn.microsoft.com/en-us/library/aa372048%28v=VS.85%29.aspx

        # Add information to Property
        # Property | Value
        # Update version
        view = database.OpenView(
            "UPDATE Property SET Value='%s' WHERE Property='ProductVersion'" %
            self.exefile.get_fileversion_as_string())
        view.Execute(None)
        view = database.OpenView(
            "UPDATE Property Set Value='%s' WHERE Property='ProductCode'" %
            self.product_GUID)
        view.Execute(None)

        database.Commit()
예제 #25
0
파일: setup.py 프로젝트: KDE/kajongg
 def add_config(self, fullname):
     """add the uninstaller icon"""
     windist.bdist_msi.add_config(self, fullname)
     msilib.add_data(self.db, "Registry", [("DisplayIcon",  # Registry
                                            -1,  # Root
                                            r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" %
                                            self.productcode(),  # Key
                                            "DisplayIcon",  # Name
                                            r"[icons]kajongg.ico",  # Value
                                            "TARGETDIR")])  # default Component
예제 #26
0
    def add_files(self):
        db = self.db
        cab = msilib.CAB('distfiles')
        rootdir = os.path.abspath(self.bdist_dir)
        root = Directory(db, cab, None, rootdir, 'TARGETDIR', 'SourceDir')
        f = Feature(db, 'Python', 'Python', 'Everything', 0, 1, directory='TARGETDIR')
        items = [(f, root, '')]
        for version in self.versions + [self.other_version]:
            target = 'TARGETDIR' + version
            name = default = 'Python' + version
            desc = 'Everything'
            if version is self.other_version:
                title = 'Python from another location'
                level = 2
            else:
                title = 'Python %s from registry' % version
                level = 1
            f = Feature(db, name, title, desc, 1, level, directory=target)
            dir = Directory(db, cab, root, rootdir, target, default)
            items.append((f, dir, version))

        db.Commit()
        seen = {}
        for feature, dir, version in items:
            todo = [dir]
            while todo:
                dir = todo.pop()
                for file in os.listdir(dir.absolute):
                    afile = os.path.join(dir.absolute, file)
                    if os.path.isdir(afile):
                        short = '%s|%s' % (dir.make_short(file), file)
                        default = file + version
                        newdir = Directory(db, cab, dir, file, default, short)
                        todo.append(newdir)
                    else:
                        if not dir.component:
                            dir.start_component(dir.logical, feature, 0)
                        if afile not in seen:
                            key = seen[afile] = dir.add_file(file)
                            if file == self.install_script:
                                if self.install_script_key:
                                    raise DistutilsOptionError('Multiple files with name %s' % file)
                                self.install_script_key = '[#%s]' % key
                        else:
                            key = seen[afile]
                            add_data(self.db, 'DuplicateFile', [(key + version,
                              dir.component,
                              key,
                              None,
                              dir.logical)])

            db.Commit()

        cab.commit(db)
        return
예제 #27
0
파일: setup.py 프로젝트: josharnold52/shenv
 def add_scripts(self):
     super().add_scripts()
     start = 6850
     for ver in self.versions + [self.other_version]:
         install_action = "post_batgen." + ver
         exe_prop = "PYTHON" + ver
         add_data(self.db, "CustomAction",
                 [(install_action, 50, exe_prop, '-m shenv.batgen --overwrite -f \"[EmgrBatDir]\\shenv.bat\"')])
         add_data(self.db, "InstallExecuteSequence",
                 [(install_action, "&Python%s=3" % ver, start)])
         start += 1
 def commit(self, db):
     filename = tempfile.mktemp()
     msilib.FCICreate(filename, self.files)
     print filename, os.path.getsize(filename)
     sys.stderr.write(str((self.diskId, self.index, None, "#"+self.name, None, None)) + "\n")
     msilib.add_data(db, "Media",
                     [(self.diskId, self.index, None, "#"+self.name, None, None)])
     msilib.add_stream(db, self.name, filename)
     self.diskId += 1
     db.Commit()
     os.unlink(filename)
예제 #29
0
파일: MakeMSI.py 프로젝트: cleitet/wpkg-gp
    def generate_MSI(self):
        shutil.copy(self.template, self.msifile.path)
        #1 Add exe and ini file to cab
        filelist = [(self.exefile.path, "ExeFile"), (self.inifile.path, "IniFile")]
        cabfile  = os.path.join(self.tempdir, "files.cab")
        msilib.FCICreate(cabfile, filelist)

        #2 Open the MSI database
        #database = msilib.init_database(self.msifile.path, msilib.schema, self.msifile.name,  self.productcode, self.productversion, self.manufacturer)
        #print self.msifile.path
        #msilib.add_tables(database, msilib.schema)
        database = msilib.OpenDatabase(self.msifile.path, msilib.MSIDBOPEN_DIRECT)
        msilib.add_stream(database, "Wpkg_GP.cab", cabfile)

        # Update Product Code
        summaryinformation = database.GetSummaryInformation(1)
        summaryinformation.SetProperty(msilib.PID_REVNUMBER, self.package_GUID)
        summaryinformation.Persist()
        
        # Add information to Media
        # DiskId | LastSequence | DiskPrompt | Cabinet | VolumeLabel | Source
        table = "Media"
        records = [(1, 2, None, "#Wpkg_GP.cab", None, None)]
        msilib.add_data(database, table, records)

        #CAB = msilib.CAB("Wpkg_GP.cab")
        #CAB.append(self.exefile.path, "ExeFile", "ExeFile")
        #CAB.append(self.inifile.path, "IniFile", "IniFile")
        #CAB.commit(database)

        # Add information to File
        # File | Component_ | FileName | FileSize| Version | Language | Attributes | Sequence
        table = "File"
        records = [
            ("ExeFile", "Installer", self.exefile.name, self.exefile.size, None, None, 512, 1),
            ("IniFile", "Installer", self.inifile.name, self.inifile.size, None, None, 512, 2)
            ]
        msilib.add_data(database, table, records)

        
        # Add information to CustomAction
        # Action | Type | Source | Target
        # For Type, see: http://msdn.microsoft.com/en-us/library/aa372048%28v=VS.85%29.aspx

        # Add information to Property
        # Property | Value
        # Update version
        view = database.OpenView("UPDATE Property SET Value='%s' WHERE Property='ProductVersion'" % self.exefile.get_fileversion_as_string())
        view.Execute(None)
        view = database.OpenView("UPDATE Property Set Value='%s' WHERE Property='ProductCode'" % self.product_GUID)
        view.Execute(None)

        database.Commit()
예제 #30
0
파일: msi_utils.py 프로젝트: pv/bento
def create_msi_installer(package, run_node, msi_root_node, installer_name=None, output_dir="dist"):
    meta = PackageMetadata.from_package(package)

    string_version = "%d.%d.%d" % (meta.version_major, meta.version_minor, meta.version_micro)

    fullname = "%s-%s" % (package.name, string_version)
    if installer_name is None:
        installer_name = "%s-%s.msi" % (package.name, string_version)
    parent_node = run_node.make_node(output_dir)
    if parent_node is None:
        raise IOError()
    installer_node = parent_node.make_node(installer_name)
    installer_name = installer_node.abspath()
    installer_node.parent.mkdir()

    author = meta.author

    short_version = sysconfig.get_python_version()

    has_ext_modules = True
    if has_ext_modules:
        target_version = short_version
    else:
        target_version = None

    if target_version:
        product_name = "Python %s %s" % (target_version, meta.fullname)
    else:
        product_name = "Python %s" % meta.fullname

    if target_version:
        versions = [target_version]
    else:
        versions = list(ALL_VERSIONS)

    db = msilib.init_database(installer_name, schema, product_name, msilib.gen_uuid(), string_version, author)
    msilib.add_tables(db, sequence)

    props = [("DistVersion", meta.version)]
    email = meta.author_email or meta.maintainer_email
    if email:
        props.append(("ARPCONTACT", email))
    if meta.url:
        props.append(("ARPURLINFOABOUT", meta.url))
    if props:
        add_data(db, "Property", props)

    add_find_python(db, versions)
    add_files(db, msi_root_node, versions, OTHER_VERSION)
    add_scripts(db)
    add_ui(db, fullname, versions, OTHER_VERSION)
    db.Commit()
예제 #31
0
파일: msi_utils.py 프로젝트: pv/bento
def add_files(db, msi_node, versions, other_version, install_script=None):
    if install_script is not None:
        raise NotImplementedError("Support for msi install script not yet implemented")
    cab = msilib.CAB("distfiles")
    rootdir = msi_node.abspath()

    root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir")
    f = Feature(db, "Python", "Python", "Everything", 0, 1, directory="TARGETDIR")

    items = [(f, root, "")]
    for version in versions + [other_version]:
        target = "TARGETDIR" + version
        name = default = "Python" + version
        desc = "Everything"
        if version is other_version:
            title = "Python from another location"
            level = 2
        else:
            title = "Python %s from registry" % version
            level = 1
        f = Feature(db, name, title, desc, 1, level, directory=target)
        dir = Directory(db, cab, root, rootdir, target, default)
        items.append((f, dir, version))
    db.Commit()

    seen = {}
    for feature, dir, version in items:
        todo = [dir]
        while todo:
            dir = todo.pop()
            for file in os.listdir(dir.absolute):
                afile = os.path.join(dir.absolute, file)
                if os.path.isdir(afile):
                    short = "%s|%s" % (dir.make_short(file), file)
                    default = file + version
                    newdir = Directory(db, cab, dir, file, default, short)
                    todo.append(newdir)
                else:
                    if not dir.component:
                        dir.start_component(dir.logical, feature, 0)
                    if afile not in seen:
                        key = seen[afile] = dir.add_file(file)
                        if file == install_script:
                            if install_script_key:
                                raise DistutilsOptionError("Multiple files with name %s" % file)
                            install_script_key = "[#%s]" % key
                    else:
                        key = seen[afile]
                        add_data(db, "DuplicateFile", [(key + version, dir.component, key, None, dir.logical)])
        db.Commit()
    cab.commit(db)
예제 #32
0
파일: setup.py 프로젝트: zero804/kajongg
 def add_config(self, fullname):
     """add the uninstaller icon"""
     windist.bdist_msi.add_config(self, fullname)
     msilib.add_data(
         self.db,
         "Registry",
         [(
             "DisplayIcon",  # Registry
             -1,  # Root
             r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" %
             self.productcode(),  # Key
             "DisplayIcon",  # Name
             r"[icons]kajongg.ico",  # Value
             "TARGETDIR")])  # default Component
예제 #33
0
파일: windist.py 프로젝트: adUst0/FixSubs
 def add_properties(self):
     metadata = self.distribution.metadata
     props = [('DistVersion', metadata.get_version()),
              ('DefaultUIFont', 'DlgFont8'), ('ErrorDialog', 'ErrorDlg'),
              ('Progress1', 'Install'), ('Progress2', 'installs'),
              ('MaintenanceForm_Action', 'Repair'), ('ALLUSERS', '1')]
     email = metadata.author_email or metadata.maintainer_email
     if email:
         props.append(("ARPCONTACT", email))
     if metadata.url:
         props.append(("ARPURLINFOABOUT", metadata.url))
     if self.upgrade_code is not None:
         props.append(("UpgradeCode", self.upgrade_code))
     msilib.add_data(self.db, 'Property', props)
예제 #34
0
 def add_exit_dialog(self):
     import msilib
     if self.get_license() is not None:
         self.add_licence_dialog()
     dialog = distutils.command.bdist_msi.PyDialog(self.db, "ExitDialog",
             self.x, self.y, self.width, self.height, self.modal,
             self.title, "Finish", "Finish", "Finish")
     dialog.title("Completing the [ProductName]")
     dialog.back("< Back", "Finish", active=False)
     dialog.cancel("Cancel", "Back", active=False)
     dialog.text("Description", 15, 235, 320, 20, 0x30003,
             "Click the Finish button to exit the installer.")
     button = dialog.next("Finish", "Cancel", name="Finish")
     button.event("EndDialog", "Return")
     msilib.add_data(self.db, "Property",
              [("StartClient", "1")])
     # Launch product checkbox
     c = dialog.control("LaunchAfterInstall", "CheckBox",
                        15, 200, 320, 20, 0x3,
                        "StartClient", "Launch [ProductName]", None, None)
     c.condition("Hide", 'Progress1<>"Install"')
     # 18 is for execute a .exe from install
     msilib.add_data(self.db, "CustomAction", [("LaunchNuxeoDrive", 18,
                                                "launcher.exe",
                                                self.get_executable())])
     button.event("DoAction", "LaunchNuxeoDrive",
                  'StartClient=1 and Progress1="Install"')
     msilib.add_data(self.db, "CustomAction", [("NuxeoDriveCleanUp", 18,
                                                self.get_executable(),
                                                "uninstall")])
     msilib.add_data(self.db, "InstallExecuteSequence",
                     [("NuxeoDriveCleanUp",
                       'REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE', 1260)])
예제 #35
0
 def add_exit_dialog(self):
     import msilib
     if self.get_license() is not None:
         self.add_licence_dialog()
     dialog = distutils.command.bdist_msi.PyDialog(
         self.db, "ExitDialog", self.x, self.y, self.width, self.height,
         self.modal, self.title, "Finish", "Finish", "Finish")
     dialog.title("Completing the [ProductName]")
     dialog.back("< Back", "Finish", active=False)
     dialog.cancel("Cancel", "Back", active=False)
     dialog.text("Description", 15, 235, 320, 20, 0x30003,
                 "Click the Finish button to exit the installer.")
     button = dialog.next("Finish", "Cancel", name="Finish")
     button.event("EndDialog", "Return")
     msilib.add_data(self.db, "Property", [("StartClient", "1")])
     # Launch product checkbox
     c = dialog.control("LaunchAfterInstall", "CheckBox", 15, 200, 320,
                        20, 0x3, "StartClient", "Launch [ProductName]",
                        None, None)
     c.condition("Hide", 'Progress1<>"Install"')
     # 18 is for execute a .exe from install
     msilib.add_data(self.db, "CustomAction", [
         ("LaunchNuxeoDrive", 18, "launcher.exe", self.get_executable())
     ])
     button.event("DoAction", "LaunchNuxeoDrive",
                  'StartClient=1 and Progress1="Install"')
     msilib.add_data(self.db, "CustomAction", [
         ("NuxeoDriveCleanUp", 18, self.get_executable(), "uninstall")
     ])
     msilib.add_data(
         self.db, "InstallExecuteSequence",
         [("NuxeoDriveCleanUp",
           'REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE', 1260)])
예제 #36
0
 def add_licence_dialog(self):
     msilib.add_data(self.db, 'InstallUISequence',
                     [('LicenceDialog', None, 380)])
     dialog = distutils.command.bdist_msi.PyDialog(
         self.db, 'LicenceDialog', self.x, self.y, self.width,
         self.height, self.modal, self.title, 'Next', 'Next', 'Cancel')
     dialog.text('LicenseTitle', 15, 10, 320, 20, 0x3, 'License')
     dialog.control('License', 'ScrollableText', 15, 30, 340, 200, 0x7,
                    None, self.get_licence(), None, None)
     dialog.control('LicenseAccepted', 'CheckBox', 15, 240, 320, 20,
                    0x3, 'LicenseAccepted',
                    'I have accepted this agreement', None, None)
     button = dialog.cancel('Cancel', 'Next')
     button.event('EndDialog', 'Exit')
     button = dialog.next('Next', 'Cancel', active=False)
     button.condition('Enable', 'LicenseAccepted')
     button.condition('Disable', 'not LicenseAccepted')
     button.event('EndDialog', 'Return')
예제 #37
0
 def add_properties(self):
     metadata = self.distribution.metadata
     props = [
         ('DistVersion', metadata.get_version()),
         ('DefaultUIFont', 'DlgFont8'),
         ('ErrorDialog', 'ErrorDlg'),
         ('Progress1', 'Install'),
         ('Progress2', 'installs'),
         ('MaintenanceForm_Action', 'Repair'),
         ('ALLUSERS', '2'),
         ('MSIINSTALLPERUSER', '1')]
     email = metadata.author_email or metadata.maintainer_email
     if email:
         props.append(("ARPCONTACT", email))
     if metadata.url:
         props.append(("ARPURLINFOABOUT", metadata.url))
     if self.upgrade_code is not None:
         props.append(("UpgradeCode", self.upgrade_code))
     msilib.add_data(self.db, 'Property', props)
예제 #38
0
 def add_licence_dialog(self):
     import msilib
     msilib.add_data(self.db, 'InstallUISequence',
                     [("LicenceDialog", None, 380)])
     dialog = distutils.command.bdist_msi.PyDialog(
         self.db, "LicenceDialog", self.x, self.y, self.width,
         self.height, self.modal, self.title, "Next", "Next", "Cancel")
     dialog.text("LicenseTitle", 15, 10, 320, 20, 0x3, "License")
     dialog.control("License", "ScrollableText", 15, 30, 340, 200, 0x7,
                    None, self.get_license(), None, None)
     dialog.control("LicenseAccepted", "CheckBox", 15, 240, 320, 20,
                    0x3, "LicenseAccepted",
                    "I've accepted this agreement", None, None)
     button = dialog.cancel("Cancel", "Next")
     button.event("EndDialog", "Exit")
     button = dialog.next("Next", "Cancel", active=False)
     button.condition("Enable", "LicenseAccepted")
     button.condition("Disable", "not LicenseAccepted")
     button.event("EndDialog", "Return")
예제 #39
0
파일: setup.py 프로젝트: josharnold52/shenv
    def add_ui(self):
        super().add_ui();
        
        db = self.db
        x = y = 50
        w = 370
        h = 300
        title = "[ProductName] Setup"

        # see "Dialog Style Bits"
        modal = 3      # visible | modal
        modeless = 1   # visible

        add_data(db, "Property",
             # See "DefaultUIFont Property"
             [("EmgrBatDir", "c:\\utility"),
             ])


        add_data(db, "InstallUISequence", [
                 ("SelectBatDest", "Not Installed", 1231),
                 ])
        
        #####################################################################
        # Feature (Python directory) selection
        seldlg = PyDialog(db, "SelectBatDest", x, y, w, h, modal, title,
                        "Next", "Next", "Cancel")
        seldlg.title("Select the destination for the shenv.bat file")

        seldlg.text("Hint", 15, 30, 300, 20, 3,
                    "Select the directory where the shenv.bat file is installed."
                    )
        
        seldlg.back("< Back", None, active=1)
        c = seldlg.next("Next >", "Cancel")
        order = 1
        c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1)
        c.event("EndDialog", "Return", ordering=order + 2)
        c = seldlg.cancel("Cancel", "PathEdit")  #TODO : next cointrol
        c.event("SpawnDialog", "CancelDlg")

        c = seldlg.control("PathEdit", "PathEdit", 15, 60, 300, 16, 3,
                   "EmgrBatDir", "YoMan", "Next", None)
예제 #40
0
파일: setup.py 프로젝트: prvn16/pychess
 def add_properties(self):
     metadata = self.distribution.metadata
     props = [
         ("DistVersion", metadata.get_version()),
         ("DefaultUIFont", "DlgFont8"),
         ("ErrorDialog", "ErrorDlg"),
         ("Progress1", "Install"),
         ("Progress2", "installs"),
         ("MaintenanceForm_Action", "Repair"),
         ("ALLUSERS", "2"),
         ("MSIINSTALLPERUSER", "1"),
     ]
     email = metadata.author_email or metadata.maintainer_email
     if email:
         props.append(("ARPCONTACT", email))
     if metadata.url:
         props.append(("ARPURLINFOABOUT", metadata.url))
     if self.upgrade_code is not None:
         props.append(("UpgradeCode", self.upgrade_code))
     msilib.add_data(self.db, "Property", props)
예제 #41
0
    def add_scripts(self):
        if self.install_script:
            start = 6800
            for ver in self.versions + [self.other_version]:
                install_action = "install_script." + ver
                exe_prop = "PYTHON" + ver
                add_data(self.db, "CustomAction", [(install_action, 50, exe_prop, self.install_script_key)])
                add_data(self.db, "InstallExecuteSequence", [(install_action, "&Python%s=3" % ver, start)])
                start += 1

        if self.pre_install_script:
            scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
            f = open(scriptfn, "w")
            f.write('rem ="""\n%1 %0\nexit\n"""\n')
            f.write(open(self.pre_install_script).read())
            f.close()
            add_data(self.db, "Binary", [("PreInstall", msilib.Binary(scriptfn))])
            add_data(self.db, "CustomAction", [("PreInstall", 2, "PreInstall", None)])
            add_data(self.db, "InstallExecuteSequence", [("PreInstall", "NOT Installed", 450)])
        return None
예제 #42
0
 def customize_msi(self, db):
     import msilib
     # Make the appdata folder writable to enable Windows Auto update
     msilib.add_data(db, "CustomAction", [("AllowAutoUpdate", 3234,
                     "TARGETDIR", "Icacls . /grant Users:(OI)(CI)(M,DC) /t /c /q")])
     msilib.add_data(db, "InstallExecuteSequence",
                     [("AllowAutoUpdate", 'NOT Installed', 6401)])
     # Add the possibility to bind an engine with MSI
     msilib.add_data(db, "CustomAction", [("NuxeoDriveBinder", 82,
                     self.get_win_targetName(),
                     "bind-server --password \"[TARGETPASSWORD]\" --local-folder \"[TARGETDRIVEFOLDER]\" [TARGETUSERNAME] [TARGETURL]")])
     msilib.add_data(db, "InstallExecuteSequence", [("NuxeoDriveBinder",
                           'NOT (TARGETUSERNAME="" OR TARGETURL="")', -1)])
예제 #43
0
 def add_licence_dialog(self):
     import msilib
     msilib.add_data(self.db, 'InstallUISequence',
         [("LicenceDialog", None, 380)])
     dialog = distutils.command.bdist_msi.PyDialog(self.db, "LicenceDialog",
             self.x, self.y, self.width, self.height, self.modal,
             self.title, "Next", "Next", "Cancel")
     dialog.text("LicenseTitle", 15, 10, 320, 20, 0x3, "License")
     text = dialog.control("License", "ScrollableText",
                           15, 30, 340, 200, 0x7, None,
                             self.get_license(), None, None)
     c = dialog.control("LicenseAccepted", "CheckBox",
                        15, 240, 320, 20, 0x3,
                        "LicenseAccepted", "I've accepted this agreement", None, None)
     button = dialog.cancel("Cancel", "Next")
     button.event("EndDialog", "Exit")
     button = dialog.next("Next", "Cancel", active=False)
     button.condition("Enable","LicenseAccepted")
     button.condition("Disable","not LicenseAccepted")
     button.event("EndDialog", "Return")
예제 #44
0
 def add_licence_dialog(self):
     msilib.add_data(self.db, 'InstallUISequence',  [(
         'LicenceDialog', None, 380)])
     dialog = distutils.command.bdist_msi.PyDialog(
         self.db, 'LicenceDialog',
         self.x, self.y, self.width, self.height, self.modal,
         self.title, 'Next', 'Next', 'Cancel')
     dialog.text('LicenseTitle', 15, 10, 320, 20, 0x3, 'License')
     dialog.control(
         'License', 'ScrollableText', 15, 30, 340, 200,  0x7,
         None, self.get_licence(), None, None)
     dialog.control(
         'LicenseAccepted', 'CheckBox', 15, 240, 320, 20, 0x3,
         'LicenseAccepted', 'I have accepted this agreement', None, None)
     button = dialog.cancel('Cancel', 'Next')
     button.event('EndDialog', 'Exit')
     button = dialog.next('Next', 'Cancel', active=False)
     button.condition('Enable', 'LicenseAccepted')
     button.condition('Disable', 'not LicenseAccepted')
     button.event('EndDialog', 'Return')
예제 #45
0
        def run(self):
            bdist_msi.bdist_msi.run(self)

            # Remove obsolete files.
            comp = "pygame1"  # Pygame component
            prop = comp   # Directory property
            records = [("surfarray.pyd", comp,
                        "SURFAR~1.PYD|surfarray.pyd", prop, 1),
                       ("sndarray.pyd", comp,
                        "SNDARRAY.PYD|sndarray.pyd", prop, 1),
                       ("color.py", comp, "COLOR.PY|color.py", prop, 1),
                       ("color.pyc", comp, "COLOR.PYC|color.pyc", prop, 1),
                       ("color.pyo", comp, "COLOR.PYO|color.pyo", prop, 1)]
            msilib.add_data(self.db, "RemoveFile", records)

            # Overwrite outdated files.
            fullname = self.distribution.get_fullname()
            installer_name = self.get_installer_filename(fullname)           
            print ("changing %s to overwrite files on install" % installer_name)
            msilib.add_data(self.db, "Property", [("REINSTALLMODE", "amus")])
            self.db.Commit()
예제 #46
0
        def run(self):
            bdist_msi.bdist_msi.run(self)

            # Remove obsolete files.
            comp = "pygame1"  # Pygame component
            prop = comp  # Directory property
            records = [
                ("surfarray.pyd", comp, "SURFAR~1.PYD|surfarray.pyd", prop, 1),
                ("sndarray.pyd", comp, "SNDARRAY.PYD|sndarray.pyd", prop, 1),
                ("color.py", comp, "COLOR.PY|color.py", prop, 1),
                ("color.pyc", comp, "COLOR.PYC|color.pyc", prop, 1),
                ("color.pyo", comp, "COLOR.PYO|color.pyo", prop, 1)
            ]
            msilib.add_data(self.db, "RemoveFile", records)

            # Overwrite outdated files.
            fullname = self.distribution.get_fullname()
            installer_name = self.get_installer_filename(fullname)
            print("changing %s to overwrite files on install" % installer_name)
            msilib.add_data(self.db, "Property", [("REINSTALLMODE", "amus")])
            self.db.Commit()
예제 #47
0
		def install_service(service):
			log.info('adding installer for %s service', service.name)
			comp_id = get_service_comp(service)

			msilib.add_data(self.db, 'ServiceInstall', [(
				comp_id,  # ServiceInstall
				service.name,  # Name
				# DisplayName
				getattr(service, 'display_name', service.name),
				Service.TYPE_OWN_PROCESS,  # ServiceType
				# ServiceType
				getattr(service.install, 'start', Service.START_AUTO),
				# ErrorControl
				getattr(service.install, 'error', Service.ERROR_NORMAL),
				None,  # LoadOrderGroup
				None,  # Dependencies
				None,  # StartName
				None,  # Password
				None,  # Arguments
				comp_id,  # Component_
				getattr(service, 'description', None)  # Description
			)])
예제 #48
0
 def customize_msi(self, db):
     import msilib
     # Make the appdata folder writable to enable Windows Auto update
     msilib.add_data(db, "CustomAction",
                     [("AllowAutoUpdate", 3234, "TARGETDIR",
                       "Icacls . /grant Users:(OI)(CI)(M,DC) /t /c /q")])
     msilib.add_data(db, "InstallExecuteSequence",
                     [("AllowAutoUpdate", 'NOT Installed', 6401)])
     # Add the possibility to bind an engine with MSI
     msilib.add_data(db, "CustomAction", [(
         "NuxeoDriveBinder", 82, self.get_win_targetName(),
         "bind-server --password \"[TARGETPASSWORD]\" --local-folder \"[TARGETDRIVEFOLDER]\" [TARGETUSERNAME] [TARGETURL]"
     )])
     msilib.add_data(db, "InstallExecuteSequence", [
         ("NuxeoDriveBinder", 'NOT (TARGETUSERNAME="" OR TARGETURL="")', -1)
     ])
예제 #49
0
    def add_scripts(self):
        if self.install_script:
            start = 6800
            for ver in self.versions + [self.other_version]:
                install_action = 'install_script.' + ver
                exe_prop = 'PYTHON' + ver
                add_data(self.db, 'CustomAction', [(install_action,
                  50,
                  exe_prop,
                  self.install_script_key)])
                add_data(self.db, 'InstallExecuteSequence', [(install_action, '&Python%s=3' % ver, start)])
                start += 1

        if self.pre_install_script:
            scriptfn = os.path.join(self.bdist_dir, 'preinstall.bat')
            f = open(scriptfn, 'w')
            f.write('rem ="""\n%1 %0\nexit\n"""\n')
            f.write(open(self.pre_install_script).read())
            f.close()
            add_data(self.db, 'Binary', [('PreInstall', msilib.Binary(scriptfn))])
            add_data(self.db, 'CustomAction', [('PreInstall', 2, 'PreInstall', None)])
            add_data(self.db, 'InstallExecuteSequence', [('PreInstall', 'NOT Installed', 450)])
        return None
예제 #50
0
def AddSPComponent(msiSrcPath, patch_level):
    try:

        FeatureName = GetFeatureParent(msiSrcPath)
        logger.info("FeatureName :" + str(FeatureName))
        componUUID = msilib.gen_uuid()
        patchName = str(patchType) + str(patch_level)
        logger.info("patchName :" + str(patchName))
        sp_product_name = '[ProductName] ' + patchName
        logger.info("sp_product_name :" + str(sp_product_name))
        patch_reg_key = 'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\' + sp_product_name
        MsiProductCode = GetProductCode(msiSrcPath)
        msiDB = msilib.OpenDatabase(msiSrcPath, msilib.MSIDBOPEN_TRANSACT)
        #add component for SP
        msilib.add_data(
            msiDB, 'Component',
            [(patchName + '_RegistryUninstall', componUUID, 'INSTALLDIR', 260,
              'PATCH', patchName + '_UNINSTALLSTRING')])
        msilib.add_data(msiDB, 'FeatureComponents',
                        [(FeatureName, patchName + '_RegistryUninstall')])
        msilib.add_data(msiDB, 'Registry', [
            (patchName + '_UNINSTALLSTRING', 2, patch_reg_key,
             'UninstallString', 'Msiexec.exe /uninstall ' + str(PatchUUID) +
             ' /package [ProductCode] /qb', patchName + '_RegistryUninstall'),
            (patchName + '_SHELL_ENTRY', 2, patch_reg_key, '*', '',
             patchName + '_RegistryUninstall'),
            (patchName + '_DISPLAYICON', 2, patch_reg_key, 'DisplayIcon',
             '[SetupFolder]SetupRes\\amar.ico',
             patchName + '_RegistryUninstall'),
            (patchName + '_DISPLAYNAME', 2, patch_reg_key, 'DisplayName',
             '[ProductName] ' + patchName + '-64bit ',
             patchName + '_RegistryUninstall'),
            (patchName + '_DISPLAYVERSION', 2, patch_reg_key, 'DisplayVersion',
             '[ProductVersion]', patchName + '_RegistryUninstall'),
            (patchName + '_NOMODIFY', 2, patch_reg_key, 'NoModify', '#1',
             patchName + '_RegistryUninstall'),
            (patchName + '_NOREMOVE', 2, patch_reg_key, 'NoRemove', '#0',
             patchName + '_RegistryUninstall'),
            (patchName + '_NOREPAIR', 2, patch_reg_key, 'NoRepair', '#1',
             patchName + '_RegistryUninstall'),
            (patchName + '_PARENTDISPLAYNAME', 2, patch_reg_key,
             'ParentDisplayName', '[ProductName]',
             patchName + '_RegistryUninstall'),
            (patchName + '_PARENTKEYNAME', 2, patch_reg_key, 'ParentKeyName',
             '[ProductName]', patchName + '_RegistryUninstall'),
            (patchName + '_INSTALLDATE', 2, patch_reg_key, 'InstallDate',
             '[Date]', patchName + '_RegistryUninstall'),
            (patchName + '_RELEASETYPE', 2, patch_reg_key, 'ReleaseType',
             'Product Update', patchName + '_RegistryUninstall'),
            (patchName + '_PUBLISHER', 2, patch_reg_key, 'Publisher',
             '[Manufacturer]', patchName + '_RegistryUninstall')
        ])
        msiDB.Commit()
    except Exception as E:
        logger.info("Exception in AddSPComponent is:" + str(E))
예제 #51
0
 def generate_msi(self, document, dstroot):
     """
     generate msi from a document, using systescanmerge and registryscanmerge 
     """
     self.database = msilib.OpenDatabase(self.msiFile.path, msilib.MSIDBOPEN_DIRECT)
     self.document = document
     
     propertyRecords = self.collectPropertyRecords() 
     table = "Property"
     msilib.add_data(self.database, table, propertyRecords)
     
     promptText = self.productName + " " + self.productVersion + " [1]"
     diskPrompt = [ ("DiskPrompt", promptText ) ]
     msilib.add_data(self.database, table, diskPrompt) 
     
     self.cabFile = msilib.CAB("files.cab")
     f = msilib.Feature(self.database, "defaultFeature", "Default Feature", "Everything", 0, directory="TARGETDIR")
     f.set_current()
     
     home =  dstroot[:3] # example home = "C:\"
     
     # this is the root directory object, a parent of all subdirs in the installation
     root = msilib.Directory(self.database, self.cabFile, None, home , "TARGETDIR", "SourceDir")
     
     self.__buildMSIHiarchy(dstroot, root)
     
     # create a component in "Component" table responsible for installing the registry keys
     root.start_component(component = self.RegsitryComponent, flags = 0)
     # RegsitryComponent is set to current component by default, we don't need that right now,
     root.component = None
     
     # Create and add registry records:
     self.createRegistryRecords()
     if len(self.registryRecords) != 0:
         # there are registry changes, enable and then add them to the installer
         actionsRecords = self.enableRegistryActions()
         table = "InstallExecuteSequence"
         msilib.add_data(self.database, table, actionsRecords)
         
         # now add self.registryRecords found by calling createRegistryRecords, to the msi. a list of tuples is the format.
         table = "Registry"
         msilib.add_data(self.database, table, self.registryRecords) 
         
     self.database.Commit()
     self.cabFile.commit(self.database)
예제 #52
0
 def add_scripts(self):
     distutils.command.bdist_msi.bdist_msi.add_scripts(self)
     msilib.add_data(self.db, "RemoveFile", [
         ("cxFreezeBatch", "cx_Freeze", "cxfreeze*.bat", "Scripts", 2)
     ])
예제 #53
0
    def add_ui(self):
        db = self.db
        x = y = 50
        w = 370
        h = 300
        title = "[ProductName] Setup"

        # see "Dialog Style Bits"
        modal = 3  # visible | modal
        modeless = 1  # visible
        track_disk_space = 32

        # UI customization properties
        add_data(
            db,
            "Property",
            # See "DefaultUIFont Property"
            [
                ("DefaultUIFont", "DlgFont8"),
                # See "ErrorDialog Style Bit"
                ("ErrorDialog", "ErrorDlg"),
                ("Progress1", "Install"),  # modified in maintenance type dlg
                ("Progress2", "installs"),
                ("MaintenanceForm_Action", "Repair"),
                # possible values: ALL, JUSTME
                ("WhichUsers", "ALL")
            ])

        # Fonts, see "TextStyle Table"
        add_data(
            db,
            "TextStyle",
            [
                ("DlgFont8", "Tahoma", 9, None, 0),
                ("DlgFontBold8", "Tahoma", 8, None, 1),  #bold
                ("VerdanaBold10", "Verdana", 10, None, 1),
                ("VerdanaRed9", "Verdana", 9, 255, 0),
            ])

        # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
        # Numbers indicate sequence; see sequence.py for how these action integrate
        add_data(
            db,
            "InstallUISequence",
            [
                ("PrepareDlg", "Not Privileged or Windows9x or Installed",
                 140),
                ("WhichUsersDlg",
                 "Privileged and not Windows9x and not Installed", 141),
                # In the user interface, assume all-users installation if privileged.
                ("SelectFeaturesDlg", "Not Installed", 1230),
                # XXX no support for resume installations yet
                #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
                ("MaintenanceTypeDlg",
                 "Installed AND NOT RESUME AND NOT Preselected", 1250),
                ("ProgressDlg", None, 1280)
            ])

        add_data(db, 'ActionText', text.ActionText)
        add_data(db, 'UIText', text.UIText)
        #####################################################################
        # Standard dialogs: FatalError, UserExit, ExitDialog
        fatal = PyDialog(db, "FatalError", x, y, w, h, modal, title, "Finish",
                         "Finish", "Finish")
        fatal.title("[ProductName] Installer ended prematurely")
        fatal.back("< Back", "Finish", active=0)
        fatal.cancel("Cancel", "Back", active=0)
        fatal.text(
            "Description1", 15, 70, 320, 80, 0x30003,
            "[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."
        )
        fatal.text("Description2", 15, 155, 320, 20, 0x30003,
                   "Click the Finish button to exit the Installer.")
        c = fatal.next("Finish", "Cancel", name="Finish")
        c.event("EndDialog", "Exit")

        user_exit = PyDialog(db, "UserExit", x, y, w, h, modal, title,
                             "Finish", "Finish", "Finish")
        user_exit.title("[ProductName] Installer was interrupted")
        user_exit.back("< Back", "Finish", active=0)
        user_exit.cancel("Cancel", "Back", active=0)
        user_exit.text(
            "Description1", 15, 70, 320, 80, 0x30003,
            "[ProductName] setup was interrupted.  Your system has not been modified.  "
            "To install this program at a later time, please run the installation again."
        )
        user_exit.text("Description2", 15, 155, 320, 20, 0x30003,
                       "Click the Finish button to exit the Installer.")
        c = user_exit.next("Finish", "Cancel", name="Finish")
        c.event("EndDialog", "Exit")

        exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
                               "Finish", "Finish", "Finish")
        exit_dialog.title("Completing the [ProductName] Installer")
        exit_dialog.back("< Back", "Finish", active=0)
        exit_dialog.cancel("Cancel", "Back", active=0)
        exit_dialog.text("Description", 15, 235, 320, 20, 0x30003,
                         "Click the Finish button to exit the Installer.")
        c = exit_dialog.next("Finish", "Cancel", name="Finish")
        c.event("EndDialog", "Return")

        #####################################################################
        # Required dialog: FilesInUse, ErrorDlg
        inuse = PyDialog(
            db,
            "FilesInUse",
            x,
            y,
            w,
            h,
            19,  # KeepModeless|Modal|Visible
            title,
            "Retry",
            "Retry",
            "Retry",
            bitmap=False)
        inuse.text("Title", 15, 6, 200, 15, 0x30003,
                   r"{\DlgFontBold8}Files in Use")
        inuse.text("Description", 20, 23, 280, 20, 0x30003,
                   "Some files that need to be updated are currently in use.")
        inuse.text(
            "Text", 20, 55, 330, 50, 3,
            "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."
        )
        inuse.control("List", "ListBox", 20, 107, 330, 130, 7,
                      "FileInUseProcess", None, None, None)
        c = inuse.back("Exit", "Ignore", name="Exit")
        c.event("EndDialog", "Exit")
        c = inuse.next("Ignore", "Retry", name="Ignore")
        c.event("EndDialog", "Ignore")
        c = inuse.cancel("Retry", "Exit", name="Retry")
        c.event("EndDialog", "Retry")

        # See "Error Dialog". See "ICE20" for the required names of the controls.
        error = Dialog(
            db,
            "ErrorDlg",
            50,
            10,
            330,
            101,
            65543,  # Error|Minimize|Modal|Visible
            title,
            "ErrorText",
            None,
            None)
        error.text("ErrorText", 50, 9, 280, 48, 3, "")
        #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
        error.pushbutton("N", 120, 72, 81, 21, 3, "No",
                         None).event("EndDialog", "ErrorNo")
        error.pushbutton("Y", 240, 72, 81, 21, 3, "Yes",
                         None).event("EndDialog", "ErrorYes")
        error.pushbutton("A", 0, 72, 81, 21, 3, "Abort",
                         None).event("EndDialog", "ErrorAbort")
        error.pushbutton("C", 42, 72, 81, 21, 3, "Cancel",
                         None).event("EndDialog", "ErrorCancel")
        error.pushbutton("I", 81, 72, 81, 21, 3, "Ignore",
                         None).event("EndDialog", "ErrorIgnore")
        error.pushbutton("O", 159, 72, 81, 21, 3, "Ok",
                         None).event("EndDialog", "ErrorOk")
        error.pushbutton("R", 198, 72, 81, 21, 3, "Retry",
                         None).event("EndDialog", "ErrorRetry")

        #####################################################################
        # Global "Query Cancel" dialog
        cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, "No", "No",
                        "No")
        cancel.text(
            "Text", 48, 15, 194, 30, 3,
            "Are you sure you want to cancel [ProductName] installation?")
        #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
        #               "py.ico", None, None)
        c = cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
        c.event("EndDialog", "Exit")

        c = cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
        c.event("EndDialog", "Return")

        #####################################################################
        # Global "Wait for costing" dialog
        costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal,
                         title, "Return", "Return", "Return")
        costing.text(
            "Text", 48, 15, 194, 30, 3,
            "Please wait while the installer finishes determining your disk space requirements."
        )
        c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
        c.event("EndDialog", "Exit")

        #####################################################################
        # Preparation dialog: no user input except cancellation
        prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
                        "Cancel", "Cancel", "Cancel")
        prep.text(
            "Description", 15, 70, 320, 40, 0x30003,
            "Please wait while the Installer prepares to guide you through the installation."
        )
        prep.title("Welcome to the [ProductName] Installer")
        c = prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...")
        c.mapping("ActionText", "Text")
        c = prep.text("ActionData", 15, 135, 320, 30, 0x30003, None)
        c.mapping("ActionData", "Text")
        prep.back("Back", None, active=0)
        prep.next("Next", None, active=0)
        c = prep.cancel("Cancel", None)
        c.event("SpawnDialog", "CancelDlg")

        #####################################################################
        # Feature (Python directory) selection
        seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title,
                          "Next", "Next", "Cancel")
        seldlg.title("Select Python Installations")

        seldlg.text(
            "Hint", 15, 30, 300, 20, 3,
            "Select the Python locations where %s should be installed." %
            self.distribution.get_fullname())

        seldlg.back("< Back", None, active=0)
        c = seldlg.next("Next >", "Cancel")
        order = 1
        c.event("[TARGETDIR]", "[SourceDir]", ordering=order)
        for version in self.versions + [self.other_version]:
            order += 1
            c.event("[TARGETDIR]",
                    "[TARGETDIR%s]" % version,
                    "FEATURE_SELECTED AND &Python%s=3" % version,
                    ordering=order)
        c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1)
        c.event("EndDialog", "Return", ordering=order + 2)
        c = seldlg.cancel("Cancel", "Features")
        c.event("SpawnDialog", "CancelDlg")

        c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3,
                           "FEATURE", None, "PathEdit", None)
        c.event("[FEATURE_SELECTED]", "1")
        ver = self.other_version
        install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver
        dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver

        c = seldlg.text("Other", 15, 200, 300, 15, 3,
                        "Provide an alternate Python location")
        c.condition("Enable", install_other_cond)
        c.condition("Show", install_other_cond)
        c.condition("Disable", dont_install_other_cond)
        c.condition("Hide", dont_install_other_cond)

        c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1,
                           "TARGETDIR" + ver, None, "Next", None)
        c.condition("Enable", install_other_cond)
        c.condition("Show", install_other_cond)
        c.condition("Disable", dont_install_other_cond)
        c.condition("Hide", dont_install_other_cond)

        #####################################################################
        # Disk cost
        cost = PyDialog(db,
                        "DiskCostDlg",
                        x,
                        y,
                        w,
                        h,
                        modal,
                        title,
                        "OK",
                        "OK",
                        "OK",
                        bitmap=False)
        cost.text("Title", 15, 6, 200, 15, 0x30003,
                  r"{\DlgFontBold8}Disk Space Requirements")
        cost.text(
            "Description", 20, 20, 280, 20, 0x30003,
            "The disk space required for the installation of the selected features."
        )
        cost.text(
            "Text", 20, 53, 330, 60, 3,
            "The highlighted volumes (if any) do not have enough disk space "
            "available for the currently selected features.  You can either "
            "remove some files from the highlighted volumes, or choose to "
            "install less features onto local drive(s), or select different "
            "destination drive(s).")
        cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
                     None, "{120}{70}{70}{70}{70}", None, None)
        cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")

        #####################################################################
        # WhichUsers Dialog. Only available on NT, and for privileged users.
        # This must be run before FindRelatedProducts, because that will
        # take into account whether the previous installation was per-user
        # or per-machine. We currently don't support going back to this
        # dialog after "Next" was selected; to support this, we would need to
        # find how to reset the ALLUSERS property, and how to re-run
        # FindRelatedProducts.
        # On Windows9x, the ALLUSERS property is ignored on the command line
        # and in the Property table, but installer fails according to the documentation
        # if a dialog attempts to set ALLUSERS.
        whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
                              "AdminInstall", "Next", "Cancel")
        whichusers.title(
            "Select whether to install [ProductName] for all users of this computer."
        )
        # A radio group with two options: allusers, justme
        g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3,
                                  "WhichUsers", "", "Next")
        g.add("ALL", 0, 5, 150, 20, "Install for all users")
        g.add("JUSTME", 0, 25, 150, 20, "Install just for me")

        whichusers.back("Back", None, active=0)

        c = whichusers.next("Next >", "Cancel")
        c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
        c.event("EndDialog", "Return", ordering=2)

        c = whichusers.cancel("Cancel", "AdminInstall")
        c.event("SpawnDialog", "CancelDlg")

        #####################################################################
        # Installation Progress dialog (modeless)
        progress = PyDialog(db,
                            "ProgressDlg",
                            x,
                            y,
                            w,
                            h,
                            modeless,
                            title,
                            "Cancel",
                            "Cancel",
                            "Cancel",
                            bitmap=False)
        progress.text("Title", 20, 15, 200, 15, 0x30003,
                      r"{\DlgFontBold8}[Progress1] [ProductName]")
        progress.text(
            "Text", 35, 65, 300, 30, 3,
            "Please wait while the Installer [Progress2] [ProductName]. "
            "This may take several minutes.")
        progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")

        c = progress.text("ActionText", 70, 100, w - 70, 20, 3, "Pondering...")
        c.mapping("ActionText", "Text")

        #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
        #c.mapping("ActionData", "Text")

        c = progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10,
                             65537, None, "Progress done", None, None)
        c.mapping("SetProgress", "Progress")

        progress.back("< Back", "Next", active=False)
        progress.next("Next >", "Cancel", active=False)
        progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")

        ###################################################################
        # Maintenance type: repair/uninstall
        maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
                         "Next", "Next", "Cancel")
        maint.title("Welcome to the [ProductName] Setup Wizard")
        maint.text(
            "BodyText", 15, 63, 330, 42, 3,
            "Select whether you want to repair or remove [ProductName].")
        g = maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3,
                             "MaintenanceForm_Action", "", "Next")
        #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
        g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
        g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")

        maint.back("< Back", None, active=False)
        c = maint.next("Finish", "Cancel")
        # Change installation: Change progress dialog to "Change", then ask
        # for feature selection
        #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
        #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)

        # Reinstall: Change progress dialog to "Repair", then invoke reinstall
        # Also set list of reinstalled features to "ALL"
        c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
        c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"',
                6)
        c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
        c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)

        # Uninstall: Change progress to "Remove", then invoke uninstall
        # Also set list of removed features to "ALL"
        c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
        c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"',
                12)
        c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"',
                13)
        c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)

        # Close dialog when maintenance action scheduled
        c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
        #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)

        maint.cancel("Cancel",
                     "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
예제 #54
0
    def add_find_python(self):
        """Adds code to the installer to compute the location of Python.

        Properties PYTHON.MACHINE.X.Y and PYTHON.USER.X.Y will be set from the
        registry for each version of Python.

        Properties TARGETDIRX.Y will be set from PYTHON.USER.X.Y if defined,
        else from PYTHON.MACHINE.X.Y.

        Properties PYTHONX.Y will be set to TARGETDIRX.Y\\python.exe"""

        start = 402
        for ver in self.versions:
            install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % ver
            machine_reg = "python.machine." + ver
            user_reg = "python.user." + ver
            machine_prop = "PYTHON.MACHINE." + ver
            user_prop = "PYTHON.USER." + ver
            machine_action = "PythonFromMachine" + ver
            user_action = "PythonFromUser" + ver
            exe_action = "PythonExe" + ver
            target_dir_prop = "TARGETDIR" + ver
            exe_prop = "PYTHON" + ver
            if msilib.Win64:
                # type: msidbLocatorTypeRawValue + msidbLocatorType64bit
                Type = 2 + 16
            else:
                Type = 2
            add_data(self.db, "RegLocator",
                     [(machine_reg, 2, install_path, None, Type),
                      (user_reg, 1, install_path, None, Type)])
            add_data(self.db, "AppSearch", [(machine_prop, machine_reg),
                                            (user_prop, user_reg)])
            add_data(self.db, "CustomAction", [
                (machine_action, 51 + 256, target_dir_prop,
                 "[" + machine_prop + "]"),
                (user_action, 51 + 256, target_dir_prop,
                 "[" + user_prop + "]"),
                (exe_action, 51 + 256, exe_prop,
                 "[" + target_dir_prop + "]\\python.exe"),
            ])
            add_data(self.db, "InstallExecuteSequence", [
                (machine_action, machine_prop, start),
                (user_action, user_prop, start + 1),
                (exe_action, None, start + 2),
            ])
            add_data(self.db, "InstallUISequence", [
                (machine_action, machine_prop, start),
                (user_action, user_prop, start + 1),
                (exe_action, None, start + 2),
            ])
            add_data(self.db, "Condition",
                     [("Python" + ver, 0, "NOT TARGETDIR" + ver)])
            start += 4
            assert start < 500
예제 #55
0
    def run(self):
        if not self.skip_build:
            self.run_command('build')

        install = self.reinitialize_command('install', reinit_subcommands=1)
        install.prefix = self.bdist_dir
        install.skip_build = self.skip_build
        install.warn_dir = 0

        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

        if self.distribution.has_ext_modules():
            # If we are building an installer for a Python version other
            # than the one we are currently running, then we need to ensure
            # our build_lib reflects the other Python version rather than ours.
            # Note that for target_version!=sys.version, we must have skipped the
            # build step, so there is no issue with enforcing the build of this
            # version.
            target_version = self.target_version
            if not target_version:
                assert self.skip_build, "Should have already checked this"
                target_version = '%d.%d' % sys.version_info[:2]
            plat_specifier = ".%s-%s" % (self.plat_name, target_version)
            build = self.get_finalized_command('build')
            build.build_lib = os.path.join(build.build_base,
                                           'lib' + plat_specifier)

        log.info("installing to %s", self.bdist_dir)
        install.ensure_finalized()

        # avoid warning of 'install_lib' about installing
        # into a directory not in sys.path
        sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))

        install.run()

        del sys.path[0]

        self.mkpath(self.dist_dir)
        fullname = self.distribution.get_fullname()
        installer_name = self.get_installer_filename(fullname)
        installer_name = os.path.abspath(installer_name)
        if os.path.exists(installer_name): os.unlink(installer_name)

        metadata = self.distribution.metadata
        author = metadata.author
        if not author:
            author = metadata.maintainer
        if not author:
            author = "UNKNOWN"
        version = metadata.get_version()
        # ProductVersion must be strictly numeric
        # XXX need to deal with prerelease versions
        sversion = "%d.%d.%d" % StrictVersion(version).version
        # Prefix ProductName with Python x.y, so that
        # it sorts together with the other Python packages
        # in Add-Remove-Programs (APR)
        fullname = self.distribution.get_fullname()
        if self.target_version:
            product_name = "Python %s %s" % (self.target_version, fullname)
        else:
            product_name = "Python %s" % (fullname)
        self.db = msilib.init_database(installer_name, schema, product_name,
                                       msilib.gen_uuid(), sversion, author)
        msilib.add_tables(self.db, sequence)
        props = [('DistVersion', version)]
        email = metadata.author_email or metadata.maintainer_email
        if email:
            props.append(("ARPCONTACT", email))
        if metadata.url:
            props.append(("ARPURLINFOABOUT", metadata.url))
        if props:
            add_data(self.db, 'Property', props)

        self.add_find_python()
        self.add_files()
        self.add_scripts()
        self.add_ui()
        self.db.Commit()

        if hasattr(self.distribution, 'dist_files'):
            tup = 'bdist_msi', self.target_version or 'any', fullname
            self.distribution.dist_files.append(tup)

        if not self.keep_temp:
            remove_tree(self.bdist_dir, dry_run=self.dry_run)
예제 #56
0
 def run(self):
     if not self.skip_build:
         self.run_command('build')
     install = self.reinitialize_command('install', reinit_subcommands=1)
     install.prefix = self.bdist_dir
     install.skip_build = self.skip_build
     install.warn_dir = 0
     install_lib = self.reinitialize_command('install_lib')
     install_lib.compile = 0
     install_lib.optimize = 0
     if self.distribution.has_ext_modules():
         target_version = self.target_version
         if not target_version:
             target_version = sys.version[0:3]
         plat_specifier = '.%s-%s' % (self.plat_name, target_version)
         build = self.get_finalized_command('build')
         build.build_lib = os.path.join(build.build_base,
                                        'lib' + plat_specifier)
     log.info('installing to %s', self.bdist_dir)
     install.ensure_finalized()
     sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
     install.run()
     del sys.path[0]
     self.mkpath(self.dist_dir)
     fullname = self.distribution.get_fullname()
     installer_name = self.get_installer_filename(fullname)
     installer_name = os.path.abspath(installer_name)
     if os.path.exists(installer_name):
         os.unlink(installer_name)
     metadata = self.distribution.metadata
     author = metadata.author
     if not author:
         author = metadata.maintainer
     if not author:
         author = 'UNKNOWN'
     version = metadata.get_version()
     sversion = '%d.%d.%d' % StrictVersion(version).version
     fullname = self.distribution.get_fullname()
     if self.target_version:
         product_name = 'Python %s %s' % (self.target_version, fullname)
     else:
         product_name = 'Python %s' % fullname
     self.db = msilib.init_database(installer_name, schema, product_name,
                                    msilib.gen_uuid(), sversion, author)
     msilib.add_tables(self.db, sequence)
     props = [('DistVersion', version)]
     email = metadata.author_email or metadata.maintainer_email
     if email:
         props.append(('ARPCONTACT', email))
     if metadata.url:
         props.append(('ARPURLINFOABOUT', metadata.url))
     if props:
         add_data(self.db, 'Property', props)
     self.add_find_python()
     self.add_files()
     self.add_scripts()
     self.add_ui()
     self.db.Commit()
     if hasattr(self.distribution, 'dist_files'):
         tup = ('bdist_msi', self.target_version or 'any', fullname)
         self.distribution.dist_files.append(tup)
     if not self.keep_temp:
         remove_tree(self.bdist_dir, dry_run=self.dry_run)
예제 #57
0
    def add_ui(self):
        db = self.db
        x = y = 50
        w = 370
        h = 300
        title = '[ProductName] Setup'
        modal = 3
        modeless = 1
        add_data(db, 'Property', [('DefaultUIFont', 'DlgFont8'),
                                  ('ErrorDialog', 'ErrorDlg'),
                                  ('Progress1', 'Install'),
                                  ('Progress2', 'installs'),
                                  ('MaintenanceForm_Action', 'Repair'),
                                  ('WhichUsers', 'ALL')])
        add_data(db, 'TextStyle', [('DlgFont8', 'Tahoma', 9, None, 0),
                                   ('DlgFontBold8', 'Tahoma', 8, None, 1),
                                   ('VerdanaBold10', 'Verdana', 10, None, 1),
                                   ('VerdanaRed9', 'Verdana', 9, 255, 0)])
        add_data(
            db, 'InstallUISequence',
            [('PrepareDlg', 'Not Privileged or Windows9x or Installed', 140),
             ('WhichUsersDlg',
              'Privileged and not Windows9x and not Installed', 141),
             ('SelectFeaturesDlg', 'Not Installed', 1230),
             ('MaintenanceTypeDlg',
              'Installed AND NOT RESUME AND NOT Preselected', 1250),
             ('ProgressDlg', None, 1280)])
        add_data(db, 'ActionText', text.ActionText)
        add_data(db, 'UIText', text.UIText)
        fatal = PyDialog(db, 'FatalError', x, y, w, h, modal, title, 'Finish',
                         'Finish', 'Finish')
        fatal.title('[ProductName] Installer ended prematurely')
        fatal.back('< Back', 'Finish', active=0)
        fatal.cancel('Cancel', 'Back', active=0)
        fatal.text(
            'Description1', 15, 70, 320, 80, 196611,
            '[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.'
        )
        fatal.text('Description2', 15, 155, 320, 20, 196611,
                   'Click the Finish button to exit the Installer.')
        c = fatal.next('Finish', 'Cancel', name='Finish')
        c.event('EndDialog', 'Exit')
        user_exit = PyDialog(db, 'UserExit', x, y, w, h, modal, title,
                             'Finish', 'Finish', 'Finish')
        user_exit.title('[ProductName] Installer was interrupted')
        user_exit.back('< Back', 'Finish', active=0)
        user_exit.cancel('Cancel', 'Back', active=0)
        user_exit.text(
            'Description1', 15, 70, 320, 80, 196611,
            '[ProductName] setup was interrupted.  Your system has not been modified.  To install this program at a later time, please run the installation again.'
        )
        user_exit.text('Description2', 15, 155, 320, 20, 196611,
                       'Click the Finish button to exit the Installer.')
        c = user_exit.next('Finish', 'Cancel', name='Finish')
        c.event('EndDialog', 'Exit')
        exit_dialog = PyDialog(db, 'ExitDialog', x, y, w, h, modal, title,
                               'Finish', 'Finish', 'Finish')
        exit_dialog.title('Completing the [ProductName] Installer')
        exit_dialog.back('< Back', 'Finish', active=0)
        exit_dialog.cancel('Cancel', 'Back', active=0)
        exit_dialog.text('Description', 15, 235, 320, 20, 196611,
                         'Click the Finish button to exit the Installer.')
        c = exit_dialog.next('Finish', 'Cancel', name='Finish')
        c.event('EndDialog', 'Return')
        inuse = PyDialog(db,
                         'FilesInUse',
                         x,
                         y,
                         w,
                         h,
                         19,
                         title,
                         'Retry',
                         'Retry',
                         'Retry',
                         bitmap=False)
        inuse.text('Title', 15, 6, 200, 15, 196611,
                   '{\\DlgFontBold8}Files in Use')
        inuse.text('Description', 20, 23, 280, 20, 196611,
                   'Some files that need to be updated are currently in use.')
        inuse.text(
            'Text', 20, 55, 330, 50, 3,
            '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.'
        )
        inuse.control('List', 'ListBox', 20, 107, 330, 130, 7,
                      'FileInUseProcess', None, None, None)
        c = inuse.back('Exit', 'Ignore', name='Exit')
        c.event('EndDialog', 'Exit')
        c = inuse.next('Ignore', 'Retry', name='Ignore')
        c.event('EndDialog', 'Ignore')
        c = inuse.cancel('Retry', 'Exit', name='Retry')
        c.event('EndDialog', 'Retry')
        error = Dialog(db, 'ErrorDlg', 50, 10, 330, 101, 65543, title,
                       'ErrorText', None, None)
        error.text('ErrorText', 50, 9, 280, 48, 3, '')
        error.pushbutton('N', 120, 72, 81, 21, 3, 'No',
                         None).event('EndDialog', 'ErrorNo')
        error.pushbutton('Y', 240, 72, 81, 21, 3, 'Yes',
                         None).event('EndDialog', 'ErrorYes')
        error.pushbutton('A', 0, 72, 81, 21, 3, 'Abort',
                         None).event('EndDialog', 'ErrorAbort')
        error.pushbutton('C', 42, 72, 81, 21, 3, 'Cancel',
                         None).event('EndDialog', 'ErrorCancel')
        error.pushbutton('I', 81, 72, 81, 21, 3, 'Ignore',
                         None).event('EndDialog', 'ErrorIgnore')
        error.pushbutton('O', 159, 72, 81, 21, 3, 'Ok',
                         None).event('EndDialog', 'ErrorOk')
        error.pushbutton('R', 198, 72, 81, 21, 3, 'Retry',
                         None).event('EndDialog', 'ErrorRetry')
        cancel = Dialog(db, 'CancelDlg', 50, 10, 260, 85, 3, title, 'No', 'No',
                        'No')
        cancel.text(
            'Text', 48, 15, 194, 30, 3,
            'Are you sure you want to cancel [ProductName] installation?')
        c = cancel.pushbutton('Yes', 72, 57, 56, 17, 3, 'Yes', 'No')
        c.event('EndDialog', 'Exit')
        c = cancel.pushbutton('No', 132, 57, 56, 17, 3, 'No', 'Yes')
        c.event('EndDialog', 'Return')
        costing = Dialog(db, 'WaitForCostingDlg', 50, 10, 260, 85, modal,
                         title, 'Return', 'Return', 'Return')
        costing.text(
            'Text', 48, 15, 194, 30, 3,
            'Please wait while the installer finishes determining your disk space requirements.'
        )
        c = costing.pushbutton('Return', 102, 57, 56, 17, 3, 'Return', None)
        c.event('EndDialog', 'Exit')
        prep = PyDialog(db, 'PrepareDlg', x, y, w, h, modeless, title,
                        'Cancel', 'Cancel', 'Cancel')
        prep.text(
            'Description', 15, 70, 320, 40, 196611,
            'Please wait while the Installer prepares to guide you through the installation.'
        )
        prep.title('Welcome to the [ProductName] Installer')
        c = prep.text('ActionText', 15, 110, 320, 20, 196611, 'Pondering...')
        c.mapping('ActionText', 'Text')
        c = prep.text('ActionData', 15, 135, 320, 30, 196611, None)
        c.mapping('ActionData', 'Text')
        prep.back('Back', None, active=0)
        prep.next('Next', None, active=0)
        c = prep.cancel('Cancel', None)
        c.event('SpawnDialog', 'CancelDlg')
        seldlg = PyDialog(db, 'SelectFeaturesDlg', x, y, w, h, modal, title,
                          'Next', 'Next', 'Cancel')
        seldlg.title('Select Python Installations')
        seldlg.text(
            'Hint', 15, 30, 300, 20, 3,
            'Select the Python locations where %s should be installed.' %
            self.distribution.get_fullname())
        seldlg.back('< Back', None, active=0)
        c = seldlg.next('Next >', 'Cancel')
        order = 1
        c.event('[TARGETDIR]', '[SourceDir]', ordering=order)
        for version in self.versions + [self.other_version]:
            order += 1
            c.event('[TARGETDIR]',
                    '[TARGETDIR%s]' % version,
                    'FEATURE_SELECTED AND &Python%s=3' % version,
                    ordering=order)

        c.event('SpawnWaitDialog', 'WaitForCostingDlg', ordering=order + 1)
        c.event('EndDialog', 'Return', ordering=order + 2)
        c = seldlg.cancel('Cancel', 'Features')
        c.event('SpawnDialog', 'CancelDlg')
        c = seldlg.control('Features', 'SelectionTree', 15, 60, 300, 120, 3,
                           'FEATURE', None, 'PathEdit', None)
        c.event('[FEATURE_SELECTED]', '1')
        ver = self.other_version
        install_other_cond = 'FEATURE_SELECTED AND &Python%s=3' % ver
        dont_install_other_cond = 'FEATURE_SELECTED AND &Python%s<>3' % ver
        c = seldlg.text('Other', 15, 200, 300, 15, 3,
                        'Provide an alternate Python location')
        c.condition('Enable', install_other_cond)
        c.condition('Show', install_other_cond)
        c.condition('Disable', dont_install_other_cond)
        c.condition('Hide', dont_install_other_cond)
        c = seldlg.control('PathEdit', 'PathEdit', 15, 215, 300, 16, 1,
                           'TARGETDIR' + ver, None, 'Next', None)
        c.condition('Enable', install_other_cond)
        c.condition('Show', install_other_cond)
        c.condition('Disable', dont_install_other_cond)
        c.condition('Hide', dont_install_other_cond)
        cost = PyDialog(db,
                        'DiskCostDlg',
                        x,
                        y,
                        w,
                        h,
                        modal,
                        title,
                        'OK',
                        'OK',
                        'OK',
                        bitmap=False)
        cost.text('Title', 15, 6, 200, 15, 196611,
                  '{\\DlgFontBold8}Disk Space Requirements')
        cost.text(
            'Description', 20, 20, 280, 20, 196611,
            'The disk space required for the installation of the selected features.'
        )
        cost.text(
            'Text', 20, 53, 330, 60, 3,
            'The highlighted volumes (if any) do not have enough disk space available for the currently selected features.  You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).'
        )
        cost.control('VolumeList', 'VolumeCostList', 20, 100, 330, 150, 393223,
                     None, '{120}{70}{70}{70}{70}', None, None)
        cost.xbutton('OK', 'Ok', None, 0.5).event('EndDialog', 'Return')
        whichusers = PyDialog(db, 'WhichUsersDlg', x, y, w, h, modal, title,
                              'AdminInstall', 'Next', 'Cancel')
        whichusers.title(
            'Select whether to install [ProductName] for all users of this computer.'
        )
        g = whichusers.radiogroup('AdminInstall', 15, 60, 260, 50, 3,
                                  'WhichUsers', '', 'Next')
        g.add('ALL', 0, 5, 150, 20, 'Install for all users')
        g.add('JUSTME', 0, 25, 150, 20, 'Install just for me')
        whichusers.back('Back', None, active=0)
        c = whichusers.next('Next >', 'Cancel')
        c.event('[ALLUSERS]', '1', 'WhichUsers="ALL"', 1)
        c.event('EndDialog', 'Return', ordering=2)
        c = whichusers.cancel('Cancel', 'AdminInstall')
        c.event('SpawnDialog', 'CancelDlg')
        progress = PyDialog(db,
                            'ProgressDlg',
                            x,
                            y,
                            w,
                            h,
                            modeless,
                            title,
                            'Cancel',
                            'Cancel',
                            'Cancel',
                            bitmap=False)
        progress.text('Title', 20, 15, 200, 15, 196611,
                      '{\\DlgFontBold8}[Progress1] [ProductName]')
        progress.text(
            'Text', 35, 65, 300, 30, 3,
            'Please wait while the Installer [Progress2] [ProductName]. This may take several minutes.'
        )
        progress.text('StatusLabel', 35, 100, 35, 20, 3, 'Status:')
        c = progress.text('ActionText', 70, 100, w - 70, 20, 3, 'Pondering...')
        c.mapping('ActionText', 'Text')
        c = progress.control('ProgressBar', 'ProgressBar', 35, 120, 300, 10,
                             65537, None, 'Progress done', None, None)
        c.mapping('SetProgress', 'Progress')
        progress.back('< Back', 'Next', active=False)
        progress.next('Next >', 'Cancel', active=False)
        progress.cancel('Cancel', 'Back').event('SpawnDialog', 'CancelDlg')
        maint = PyDialog(db, 'MaintenanceTypeDlg', x, y, w, h, modal, title,
                         'Next', 'Next', 'Cancel')
        maint.title('Welcome to the [ProductName] Setup Wizard')
        maint.text(
            'BodyText', 15, 63, 330, 42, 3,
            'Select whether you want to repair or remove [ProductName].')
        g = maint.radiogroup('RepairRadioGroup', 15, 108, 330, 60, 3,
                             'MaintenanceForm_Action', '', 'Next')
        g.add('Repair', 0, 18, 200, 17, '&Repair [ProductName]')
        g.add('Remove', 0, 36, 200, 17, 'Re&move [ProductName]')
        maint.back('< Back', None, active=False)
        c = maint.next('Finish', 'Cancel')
        c.event('[REINSTALL]', 'ALL', 'MaintenanceForm_Action="Repair"', 5)
        c.event('[Progress1]', 'Repairing', 'MaintenanceForm_Action="Repair"',
                6)
        c.event('[Progress2]', 'repairs', 'MaintenanceForm_Action="Repair"', 7)
        c.event('Reinstall', 'ALL', 'MaintenanceForm_Action="Repair"', 8)
        c.event('[REMOVE]', 'ALL', 'MaintenanceForm_Action="Remove"', 11)
        c.event('[Progress1]', 'Removing', 'MaintenanceForm_Action="Remove"',
                12)
        c.event('[Progress2]', 'removes', 'MaintenanceForm_Action="Remove"',
                13)
        c.event('Remove', 'ALL', 'MaintenanceForm_Action="Remove"', 14)
        c.event('EndDialog', 'Return', 'MaintenanceForm_Action<>"Change"', 20)
        maint.cancel('Cancel',
                     'RepairRadioGroup').event('SpawnDialog', 'CancelDlg')
        return
예제 #58
0
    def add_find_python(self):
        start = 402
        for ver in self.versions:
            install_path = 'SOFTWARE\\Python\\PythonCore\\%s\\InstallPath' % ver
            machine_reg = 'python.machine.' + ver
            user_reg = 'python.user.' + ver
            machine_prop = 'PYTHON.MACHINE.' + ver
            user_prop = 'PYTHON.USER.' + ver
            machine_action = 'PythonFromMachine' + ver
            user_action = 'PythonFromUser' + ver
            exe_action = 'PythonExe' + ver
            target_dir_prop = 'TARGETDIR' + ver
            exe_prop = 'PYTHON' + ver
            if msilib.Win64:
                Type = 18
            else:
                Type = 2
            add_data(self.db, 'RegLocator',
                     [(machine_reg, 2, install_path, None, Type),
                      (user_reg, 1, install_path, None, Type)])
            add_data(self.db, 'AppSearch', [(machine_prop, machine_reg),
                                            (user_prop, user_reg)])
            add_data(
                self.db, 'CustomAction',
                [(machine_action, 307, target_dir_prop,
                  '[' + machine_prop + ']'),
                 (user_action, 307, target_dir_prop, '[' + user_prop + ']'),
                 (exe_action, 307, exe_prop,
                  '[' + target_dir_prop + ']\\python.exe')])
            add_data(self.db, 'InstallExecuteSequence',
                     [(machine_action, machine_prop, start),
                      (user_action, user_prop, start + 1),
                      (exe_action, None, start + 2)])
            add_data(self.db, 'InstallUISequence',
                     [(machine_action, machine_prop, start),
                      (user_action, user_prop, start + 1),
                      (exe_action, None, start + 2)])
            add_data(self.db, 'Condition',
                     [('Python' + ver, 0, 'NOT TARGETDIR' + ver)])
            start += 4

        return