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)])
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_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
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_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_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_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", 82, "launcher.exe", self.get_executable()) ]) button.event("DoAction", "LaunchNuxeoDrive", 'StartClient=1 and Progress1="Install"') msilib.add_data(self.db, "CustomAction", [ ("NuxeoDriveCleanUp", 82, self.get_executable(), "uninstall") ]) # Deffered action with noImpersonate to have the correct privileges msilib.add_data(self.db, "CustomAction", [("NuxeoDriveFolderCleanUp", 3234, "TARGETDIR", "cmd.exe /C \"rmdir /S /Q appdata\"")]) msilib.add_data( self.db, "InstallExecuteSequence", [("NuxeoDriveCleanUp", 'REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE', 1260)]) # After InstallInitialize msilib.add_data( self.db, "InstallExecuteSequence", [("NuxeoDriveFolderCleanUp", 'REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE', 1560)]) # Add product icon 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))]) # Allow to customize the MSI if getattr(self.attribs, 'customize_msi', None) is not None: self.attribs.customize_msi(self.db)
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)) 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_config(self, fullname): if self.add_to_path: p = "Path" if self.all_users: p = "=-*" + p msilib.add_data( self.db, "Environment", [("E_PATH", p, r"[~];[TARGETDIR]", "TARGETDIR")], ) if self.directories: msilib.add_data(self.db, "Directory", self.directories) if self.environment_variables: msilib.add_data(self.db, "Environment", self.environment_variables) # This is needed in case the AlwaysInstallElevated policy is set. # Otherwise installation will not end up in TARGETDIR. msilib.add_data(self.db, "Property", [("SecureCustomProperties", "TARGETDIR")]) msilib.add_data( self.db, "CustomAction", [( "A_SET_TARGET_DIR", 256 + 51, "TARGETDIR", self.initial_target_dir, )], ) msilib.add_data( self.db, "InstallExecuteSequence", [("A_SET_TARGET_DIR", 'TARGETDIR=""', 401)], ) msilib.add_data( self.db, "InstallUISequence", [ ("PrepareDlg", None, 140), ("A_SET_TARGET_DIR", 'TARGETDIR=""', 401), ("SelectDirectoryDlg", "not Installed", 1230), ( "MaintenanceTypeDlg", "Installed and not Resume and not Preselected", 1250, ), ("ProgressDlg", None, 1280), ], ) for index, executable in enumerate(self.distribution.executables): if (executable.shortcut_name is not None and executable.shortcut_dir is not None): baseName = os.path.basename(executable.target_name) msilib.add_data( self.db, "Shortcut", [( "S_APP_%s" % index, executable.shortcut_dir, executable.shortcut_name, "TARGETDIR", "[TARGETDIR]%s" % baseName, None, None, None, None, None, None, None, )], ) for tableName, data in self.data.items(): col = self._binary_columns.get(tableName) if col is not None: data = [(*row[:col], msilib.Binary(row[col]), *row[col + 1:]) for row in data] msilib.add_data(self.db, tableName, data) # If provided, add data to MSI's summary information stream if len(self.summary_data) > 0: for k in self.summary_data: if k not in ["author", "comments", "keywords"]: raise Exception( f"Unknown key provided in summary-data: {k!r}") summaryInfo = self.db.GetSummaryInformation(5) if "author" in self.summary_data: summaryInfo.SetProperty(msilib.PID_AUTHOR, self.summary_data["author"]) if "comments" in self.summary_data: summaryInfo.SetProperty(msilib.PID_COMMENTS, self.summary_data["comments"]) if "keywords" in self.summary_data: summaryInfo.SetProperty(msilib.PID_KEYWORDS, self.summary_data["keywords"]) summaryInfo.Persist()
def package(**setup_options): """Build a Windows .MSI package.""" class BuildExeCommand(cx_Freeze.build_exe): """Custom build_exe command.""" def run(self): """Run build_exe command.""" build_icon() build_docs() # only include 32-bit DLLs build_manifest(INCLUDE_FILES + ('pcbasic/lib/win32_x86/*',), EXCLUDE_FILES) cx_Freeze.build_exe.run(self) build_dir = 'build/exe.{}/'.format(PLATFORM_TAG) # build_exe just includes everything inside the directory # so remove some stuff we don't need for root, _, files in os.walk(build_dir + 'lib'): testing = set(root.split(os.sep)) & set(('test', 'tests', 'testing', 'examples')) for fname in files: name = os.path.join(root, fname) if ( # remove superfluous copies of python27.dll in lib/ # as there is a copy in the package root already fname.lower() == 'python27.dll' or fname.lower() == 'msvcr90.dll' # remove tests and examples or testing # we're only producing packages for win32_x86 or 'win32_x64' in name or name.endswith('.dylib') ): remove(name) # remove lib dir altogether to avoid it getting copied into the msi # as everything in there is copied once already prune('build/lib') # remove c++ runtime etc remove(build_dir + 'msvcm90.dll') remove(build_dir + 'msvcp90.dll') # remove modules that can be left out for module in ('distutils', 'setuptools', 'pydoc_data'): prune(build_dir + 'lib/%s' % module) class BdistMsiCommand(cx_Freeze.bdist_msi): """Custom bdist_msi command.""" def run(self): """Run build_msi command.""" name = '{}-{}'.format(NAME, VERSION) remove('dist/{}.msi'.format(name)) cx_Freeze.bdist_msi.run(self) # close the database file so we can rename the file del self.db os.rename('dist/{}-win32.msi'.format(name), 'dist/{}.msi'.format(name)) wash() def add_config(self, fullname): """Override cx_Freeze add_config.""" # mostly copy-paste from cxfreeze source, wich some changes if self.directories: msilib.add_data(self.db, "Directory", self.directories) msilib.add_data( self.db, 'CustomAction', [("A_SET_TARGET_DIR", 256 + 51, "TARGETDIR", self.initial_target_dir)] ) if self.add_to_path: msilib.add_data( self.db, 'Environment', [("E_PATH", "=-*Path", r"[~];[TARGETDIR]", "TARGETDIR")] ) msilib.add_data(self.db, 'InstallUISequence', [ ("PrepareDlg", None, 140), # this is new # sould probably be conditional on "not already installed" or smth ("WhichUsersDlg", "not Installed", 400), ("A_SET_TARGET_DIR", 'TARGETDIR=""', 401), ("SelectDirectoryDlg", "not Installed", 1230), ("MaintenanceTypeDlg", "Installed and not Resume and not Preselected", 1250), ("ProgressDlg", None, 1280), ]) msilib.add_data(self.db, 'InstallExecuteSequence', [ ("A_SET_TARGET_DIR", 'TARGETDIR=""', 401), ('WriteEnvironmentStrings', 'MSIINSTALLPERUSER=""', 5200), ]) for index, executable in enumerate(self.distribution.executables): if executable.shortcutName is not None and executable.shortcutDir is not None: base_name = os.path.basename(executable.targetName) msilib.add_data( self.db, "Shortcut", [( "S_APP_%s" % index, executable.shortcutDir, executable.shortcutName, "TARGETDIR", "[TARGETDIR]%s" % base_name, None, None, None, None, None, None, None )] ) for table_name, data in self.data.items(): msilib.add_data(self.db, table_name, data) def add_properties(self): """Override cx_Freeze add_properties.""" # mostly copy-paste from cxfreeze 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) def _add_whichusers_dialog(self): """Per-user or per-machine install dialog.""" # based on dialog from cpython 2.7 source code # https://svn.python.org/projects/python/trunk/Tools/msi/msi.py whichusers = distutils.command.bdist_msi.PyDialog( self.db, "WhichUsersDlg", self.x, self.y, self.width, self.height, self.modal, self.title, "AdminInstall", "Next", "Cancel" ) whichusers.title( "Select for which users to install [ProductName]." ) # A radio group with two options: allusers, justme radio = whichusers.radiogroup( "AdminInstall", 135, 60, 235, 80, 3, "WhichUsers", "", "Next" ) radio.condition("Disable", "VersionNT=600") # Not available on Vista and Windows 2008 radio.add("ALL", 0, 5, 150, 20, "Install for all users") radio.add("JUSTME", 0, 25, 235, 20, "Install just for me") whichusers.back("Back", None, active=0) button = whichusers.next("Next >", "Cancel") # SetProperty events # https://docs.microsoft.com/en-us/windows/desktop/Msi/setproperty-controlevent button.event("[MSIINSTALLPERUSER]", "{}", 'WhichUsers="ALL"', 1) button.event("[MSIINSTALLPERUSER]", "1", 'WhichUsers="JUSTME"', 1) # set the target dir to the default location for per-user/per-machine installs button.event( "[TARGETDIR]", "[ProgramFilesFolder]\\%s %s" % (NAME, SHORT_VERSION), 'WhichUsers="JUSTME"', 1 ) button.event("EndDialog", "Return", 3) button = whichusers.cancel("Cancel", "AdminInstall") button.event("SpawnDialog", "CancelDlg") def add_ui(self): self._add_whichusers_dialog() cx_Freeze.bdist_msi.add_ui(self) # remove the WriteEnvironmentStrings action from the default list # since cx_Freeze picks up the default list and puts it into the MSI # but we can't have environment changes for per-user installs (?) sequence = msilib.sequence.InstallExecuteSequence for index, info in enumerate(sequence): if info[0] == u'WriteEnvironmentStrings': break del sequence[index] # setup commands setup_options['cmdclass'] = dict( build_exe=BuildExeCommand, bdist_msi=BdistMsiCommand, **COMMANDS ) numversion = '.'.join(v for v in VERSION.encode('ascii').split('.') if v.isdigit()) # these must be bytes for cx_Freeze bdist_msi setup_options['name'] = NAME.encode('ascii') setup_options['author'] = AUTHOR.encode('ascii') setup_options['version'] = numversion # compile separately, as they end up in the wrong place anyway setup_options['ext_modules'] = [] # gui launcher setup_options['entry_points']['gui_scripts'] = ['pcbasicw=pcbasic:main'] directory_table = [ ( 'StartMenuFolder', 'TARGETDIR', '.', ), ( 'MyProgramMenu', 'StartMenuFolder', 'PCBASI~1|PC-BASIC {}'.format(SHORT_VERSION), ), ] # https://stackoverflow.com/questions/15734703/use-cx-freeze-to-create-an-msi-that-adds-a-shortcut-to-the-desktop#15736406 shortcut_table = [ ( 'ProgramShortcut', # Shortcut 'MyProgramMenu', # Directory_ 'PC-BASIC %s' % VERSION, # Name 'TARGETDIR', # Component_ '[TARGETDIR]pcbasicw.exe',# Target None, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd # PersonalFolder is My Documents, use as Start In folder 'PersonalFolder' # WkDir ), ( 'DocShortcut', # Shortcut 'MyProgramMenu', # Directory_ 'Documentation', # Name 'TARGETDIR', # Component_ '[TARGETDIR]PC-BASIC_documentation.html', # Target None, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd 'TARGETDIR' # WkDir ), ( 'SettingsShortcut', # Shortcut 'MyProgramMenu', # Directory_ 'Settings', # Name 'TARGETDIR', # Component_ '[AppDataFolder]pcbasic-{}\\PCBASIC.INI'.format(SHORT_VERSION), # Target None, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd 'TARGETDIR' # WkDir ), ( 'UninstallShortcut', # Shortcut 'MyProgramMenu', # Directory_ 'Uninstall', # Name 'TARGETDIR', # Component_ '[SystemFolder]msiexec.exe', # Target '/x %s' % PRODUCT_CODE, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd # PersonalFolder is My Documents, use as Start In folder 'TARGETDIR' # WkDir ), ] msi_data = { 'Directory': directory_table, 'Shortcut': shortcut_table, 'Icon': [('PC-BASIC-Icon', msilib.Binary('resources/pcbasic.ico')),], 'Property': [('ARPPRODUCTICON', 'PC-BASIC-Icon'),], } # cx_Freeze options setup_options['options'] = { 'build_exe': { 'packages': ['pkg_resources._vendor'], 'excludes': [ 'Tkinter', '_tkinter', 'PIL', 'PyQt4', 'scipy', 'pygame', 'pywin', 'win32com', 'test', ], 'include_files': ['doc/PC-BASIC_documentation.html'], 'include_msvcr': True, #'optimize': 2, }, 'bdist_msi': { 'data': msi_data, # add console entry points to PATH 'add_to_path': True, # enforce removal of old versions 'upgrade_code': UPGRADE_CODE, 'product_code': PRODUCT_CODE, 'initial_target_dir': 'c:\\Program Files\\%s %s' % (NAME, SHORT_VERSION), }, } setup_options['executables'] = [ Executable( 'pc-basic', base='Console', targetName='pcbasic.exe', icon='resources/pcbasic.ico', copyright=COPYRIGHT), Executable( 'pc-basic', base='Win32GUI', targetName='pcbasicw.exe', icon='resources/pcbasic.ico', #shortcutName='PC-BASIC %s' % VERSION, shortcutDir='MyProgramMenu', copyright=COPYRIGHT), ] # call cx_Freeze's setup() with command bdist_msi cx_Freeze.setup(script_args=['bdist_msi'], **setup_options)
build_cxf.sub_commands(self) def initialize_options(self): build_extra.build_extra.initialize_options(self) build_cxf.initialize_options(self) def finalize_options(self): build_extra.build_extra.finalize_options(self) build_cxf.finalize_options(self) include_files = [] for i in data_files(): for j in i[1]: include_files.append((j, i[0])) icon_table = [('GourmetIco', msilib.Binary('data/icons/gourmet.ico'))] property_table = [ ('ARPPRODUCTICON', 'GourmetIco'), ] msi_data = { 'Icon': icon_table, 'Property': property_table, } kwargs = dict( name="Gourmet Recipe Manager", executables=[ Executable(os.path.join(srcpath, 'bin', 'gourmet'), base="Win32GUI",
'[SystemFolder]msiexec.exe', # Target '/x %s' % PRODUCT_CODE, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd # PersonalFolder is My Documents, use as Start In folder 'TARGETDIR' # WkDir ), ] msi_data = { 'Directory': directory_table, 'Shortcut': shortcut_table, 'Icon': [ ('PC-BASIC-Icon', msilib.Binary('resources/pcbasic.ico')), ], 'Property': [ ('ARPPRODUCTICON', 'PC-BASIC-Icon'), ], } # cx_Freeze options SETUP_OPTIONS['options'] = { 'build_exe': { 'packages': ['numpy', 'pkg_resources._vendor'], 'excludes': [ 'Tkinter', '_tkinter', 'PIL', 'PyQt4',
'TARGETDIR', # Component_ '[SystemFolder]msiexec.exe', # Target '/x %s' % PRODUCT_CODE, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd # PersonalFolder is My Documents, use as Start In folder 'TARGETDIR' # WkDir ), ] msi_data = { 'Directory': directory_table, 'Shortcut': shortcut_table, 'Icon': [('PC-BASIC-Icon', msilib.Binary('icons/pcbasic.ico')),], 'Property': [('ARPPRODUCTICON', 'PC-BASIC-Icon'),], } # cx_Freeze options SETUP_OPTIONS['options'] = { 'build_exe': { 'packages': ['numpy', 'pkg_resources._vendor'], 'excludes': [ 'Tkinter', '_tkinter', 'PIL', 'PyQt4', 'scipy', 'pygame', 'pywin', 'win32com', 'test', ], 'include_files': ['doc/PC-BASIC_documentation.html'], 'include_msvcr': True, #'optimize': 2, },
if sys.platform == 'win32': base = 'Win32GUI' include_files = [ 'D:/Python 3.6.1/DLLs/tcl86t.dll', 'D:/Python 3.6.1/DLLs/tk86t.dll', 'E:/Programming/Python/Watch for dummies/queries.xml' ] build_exe_options = { 'include_files': include_files, 'include_msvcr': True # skip error msvcr100.dll missing } icon_table = [( PRODUCT_NAME + ' Icon', # Name msilib.Binary(ICON), # Data - .ico, .dll or .exe )] # http://msdn.microsoft.com/en-us/library/windows/desktop/aa371847(v=vs.85).aspx shortcut_table = [( START_MENU_KEY, # Shortcut START_MENU_FOLDER, # Directory_ PRODUCT_NAME, # Name 'TARGETDIR', # Component_ '[TARGETDIR]' + PRODUCT_NAME + '.exe', # Target None, # Arguments None, # Description None, # Hotkey None, # Icon None, # IconIndex None, # ShowCmd