Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes | Static Public Attributes
distutils.command.bdist_msi.bdist_msi Class Reference
Inheritance diagram for distutils.command.bdist_msi.bdist_msi:
Inheritance graph
[legend]
Collaboration diagram for distutils.command.bdist_msi.bdist_msi:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def initialize_options
def finalize_options
def run
def add_files
def add_find_python
def add_scripts
def add_ui
def get_installer_filename

Public Attributes

 bdist_dir
 plat_name
 keep_temp
 no_target_compile
 no_target_optimize
 target_version
 dist_dir
 skip_build
 install_script
 pre_install_script
 versions
 install_script_key
 db

Static Public Attributes

string description = "create a Microsoft Installer (.msi) binary distribution"
list user_options
list boolean_options
list all_versions
string other_version = 'X'

Detailed Description

Definition at line 83 of file bdist_msi.py.


Member Function Documentation

Definition at line 269 of file bdist_msi.py.

00269 
00270     def add_files(self):
00271         db = self.db
00272         cab = msilib.CAB("distfiles")
00273         rootdir = os.path.abspath(self.bdist_dir)
00274 
00275         root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir")
00276         f = Feature(db, "Python", "Python", "Everything",
00277                     0, 1, directory="TARGETDIR")
00278 
00279         items = [(f, root, '')]
00280         for version in self.versions + [self.other_version]:
00281             target = "TARGETDIR" + version
00282             name = default = "Python" + version
00283             desc = "Everything"
00284             if version is self.other_version:
00285                 title = "Python from another location"
00286                 level = 2
00287             else:
00288                 title = "Python %s from registry" % version
00289                 level = 1
00290             f = Feature(db, name, title, desc, 1, level, directory=target)
00291             dir = Directory(db, cab, root, rootdir, target, default)
00292             items.append((f, dir, version))
00293         db.Commit()
00294 
00295         seen = {}
00296         for feature, dir, version in items:
00297             todo = [dir]
00298             while todo:
00299                 dir = todo.pop()
00300                 for file in os.listdir(dir.absolute):
00301                     afile = os.path.join(dir.absolute, file)
00302                     if os.path.isdir(afile):
00303                         short = "%s|%s" % (dir.make_short(file), file)
00304                         default = file + version
00305                         newdir = Directory(db, cab, dir, file, default, short)
00306                         todo.append(newdir)
00307                     else:
00308                         if not dir.component:
00309                             dir.start_component(dir.logical, feature, 0)
00310                         if afile not in seen:
00311                             key = seen[afile] = dir.add_file(file)
00312                             if file==self.install_script:
00313                                 if self.install_script_key:
00314                                     raise DistutilsOptionError(
00315                                           "Multiple files with name %s" % file)
00316                                 self.install_script_key = '[#%s]' % key
00317                         else:
00318                             key = seen[afile]
00319                             add_data(self.db, "DuplicateFile",
00320                                 [(key + version, dir.component, key, None, dir.logical)])
00321             db.Commit()
00322         cab.commit(db)

Here is the call graph for this function:

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

Definition at line 323 of file bdist_msi.py.

00323 
00324     def add_find_python(self):
00325         """Adds code to the installer to compute the location of Python.
00326 
00327         Properties PYTHON.MACHINE.X.Y and PYTHON.USER.X.Y will be set from the
00328         registry for each version of Python.
00329 
00330         Properties TARGETDIRX.Y will be set from PYTHON.USER.X.Y if defined,
00331         else from PYTHON.MACHINE.X.Y.
00332 
00333         Properties PYTHONX.Y will be set to TARGETDIRX.Y\\python.exe"""
00334 
00335         start = 402
00336         for ver in self.versions:
00337             install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % ver
00338             machine_reg = "python.machine." + ver
00339             user_reg = "python.user." + ver
00340             machine_prop = "PYTHON.MACHINE." + ver
00341             user_prop = "PYTHON.USER." + ver
00342             machine_action = "PythonFromMachine" + ver
00343             user_action = "PythonFromUser" + ver
00344             exe_action = "PythonExe" + ver
00345             target_dir_prop = "TARGETDIR" + ver
00346             exe_prop = "PYTHON" + ver
00347             if msilib.Win64:
00348                 # type: msidbLocatorTypeRawValue + msidbLocatorType64bit
00349                 Type = 2+16
00350             else:
00351                 Type = 2
00352             add_data(self.db, "RegLocator",
00353                     [(machine_reg, 2, install_path, None, Type),
00354                      (user_reg, 1, install_path, None, Type)])
00355             add_data(self.db, "AppSearch",
00356                     [(machine_prop, machine_reg),
00357                      (user_prop, user_reg)])
00358             add_data(self.db, "CustomAction",
00359                     [(machine_action, 51+256, target_dir_prop, "[" + machine_prop + "]"),
00360                      (user_action, 51+256, target_dir_prop, "[" + user_prop + "]"),
00361                      (exe_action, 51+256, exe_prop, "[" + target_dir_prop + "]\\python.exe"),
00362                     ])
00363             add_data(self.db, "InstallExecuteSequence",
00364                     [(machine_action, machine_prop, start),
00365                      (user_action, user_prop, start + 1),
00366                      (exe_action, None, start + 2),
00367                     ])
00368             add_data(self.db, "InstallUISequence",
00369                     [(machine_action, machine_prop, start),
00370                      (user_action, user_prop, start + 1),
00371                      (exe_action, None, start + 2),
00372                     ])
00373             add_data(self.db, "Condition",
00374                     [("Python" + ver, 0, "NOT TARGETDIR" + ver)])
00375             start += 4
00376             assert start < 500

Here is the call graph for this function:

Definition at line 377 of file bdist_msi.py.

00377 
00378     def add_scripts(self):
00379         if self.install_script:
00380             start = 6800
00381             for ver in self.versions + [self.other_version]:
00382                 install_action = "install_script." + ver
00383                 exe_prop = "PYTHON" + ver
00384                 add_data(self.db, "CustomAction",
00385                         [(install_action, 50, exe_prop, self.install_script_key)])
00386                 add_data(self.db, "InstallExecuteSequence",
00387                         [(install_action, "&Python%s=3" % ver, start)])
00388                 start += 1
00389         # XXX pre-install scripts are currently refused in finalize_options()
00390         #     but if this feature is completed, it will also need to add
00391         #     entries for each version as the above code does
00392         if self.pre_install_script:
00393             scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
00394             f = open(scriptfn, "w")
00395             # The batch file will be executed with [PYTHON], so that %1
00396             # is the path to the Python interpreter; %0 will be the path
00397             # of the batch file.
00398             # rem ="""
00399             # %1 %0
00400             # exit
00401             # """
00402             # <actual script>
00403             f.write('rem ="""\n%1 %0\nexit\n"""\n')
00404             f.write(open(self.pre_install_script).read())
00405             f.close()
00406             add_data(self.db, "Binary",
00407                 [("PreInstall", msilib.Binary(scriptfn))
00408                 ])
00409             add_data(self.db, "CustomAction",
00410                 [("PreInstall", 2, "PreInstall", None)
00411                 ])
00412             add_data(self.db, "InstallExecuteSequence",
00413                     [("PreInstall", "NOT Installed", 450)])
00414 

Here is the call graph for this function:

Definition at line 415 of file bdist_msi.py.

00415 
00416     def add_ui(self):
00417         db = self.db
00418         x = y = 50
00419         w = 370
00420         h = 300
00421         title = "[ProductName] Setup"
00422 
00423         # see "Dialog Style Bits"
00424         modal = 3      # visible | modal
00425         modeless = 1   # visible
00426         track_disk_space = 32
00427 
00428         # UI customization properties
00429         add_data(db, "Property",
00430                  # See "DefaultUIFont Property"
00431                  [("DefaultUIFont", "DlgFont8"),
00432                   # See "ErrorDialog Style Bit"
00433                   ("ErrorDialog", "ErrorDlg"),
00434                   ("Progress1", "Install"),   # modified in maintenance type dlg
00435                   ("Progress2", "installs"),
00436                   ("MaintenanceForm_Action", "Repair"),
00437                   # possible values: ALL, JUSTME
00438                   ("WhichUsers", "ALL")
00439                  ])
00440 
00441         # Fonts, see "TextStyle Table"
00442         add_data(db, "TextStyle",
00443                  [("DlgFont8", "Tahoma", 9, None, 0),
00444                   ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
00445                   ("VerdanaBold10", "Verdana", 10, None, 1),
00446                   ("VerdanaRed9", "Verdana", 9, 255, 0),
00447                  ])
00448 
00449         # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
00450         # Numbers indicate sequence; see sequence.py for how these action integrate
00451         add_data(db, "InstallUISequence",
00452                  [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
00453                   ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
00454                   # In the user interface, assume all-users installation if privileged.
00455                   ("SelectFeaturesDlg", "Not Installed", 1230),
00456                   # XXX no support for resume installations yet
00457                   #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
00458                   ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
00459                   ("ProgressDlg", None, 1280)])
00460 
00461         add_data(db, 'ActionText', text.ActionText)
00462         add_data(db, 'UIText', text.UIText)
00463         #####################################################################
00464         # Standard dialogs: FatalError, UserExit, ExitDialog
00465         fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
00466                      "Finish", "Finish", "Finish")
00467         fatal.title("[ProductName] Installer ended prematurely")
00468         fatal.back("< Back", "Finish", active = 0)
00469         fatal.cancel("Cancel", "Back", active = 0)
00470         fatal.text("Description1", 15, 70, 320, 80, 0x30003,
00471                    "[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.")
00472         fatal.text("Description2", 15, 155, 320, 20, 0x30003,
00473                    "Click the Finish button to exit the Installer.")
00474         c=fatal.next("Finish", "Cancel", name="Finish")
00475         c.event("EndDialog", "Exit")
00476 
00477         user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
00478                      "Finish", "Finish", "Finish")
00479         user_exit.title("[ProductName] Installer was interrupted")
00480         user_exit.back("< Back", "Finish", active = 0)
00481         user_exit.cancel("Cancel", "Back", active = 0)
00482         user_exit.text("Description1", 15, 70, 320, 80, 0x30003,
00483                    "[ProductName] setup was interrupted.  Your system has not been modified.  "
00484                    "To install this program at a later time, please run the installation again.")
00485         user_exit.text("Description2", 15, 155, 320, 20, 0x30003,
00486                    "Click the Finish button to exit the Installer.")
00487         c = user_exit.next("Finish", "Cancel", name="Finish")
00488         c.event("EndDialog", "Exit")
00489 
00490         exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
00491                              "Finish", "Finish", "Finish")
00492         exit_dialog.title("Completing the [ProductName] Installer")
00493         exit_dialog.back("< Back", "Finish", active = 0)
00494         exit_dialog.cancel("Cancel", "Back", active = 0)
00495         exit_dialog.text("Description", 15, 235, 320, 20, 0x30003,
00496                    "Click the Finish button to exit the Installer.")
00497         c = exit_dialog.next("Finish", "Cancel", name="Finish")
00498         c.event("EndDialog", "Return")
00499 
00500         #####################################################################
00501         # Required dialog: FilesInUse, ErrorDlg
00502         inuse = PyDialog(db, "FilesInUse",
00503                          x, y, w, h,
00504                          19,                # KeepModeless|Modal|Visible
00505                          title,
00506                          "Retry", "Retry", "Retry", bitmap=False)
00507         inuse.text("Title", 15, 6, 200, 15, 0x30003,
00508                    r"{\DlgFontBold8}Files in Use")
00509         inuse.text("Description", 20, 23, 280, 20, 0x30003,
00510                "Some files that need to be updated are currently in use.")
00511         inuse.text("Text", 20, 55, 330, 50, 3,
00512                    "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.")
00513         inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
00514                       None, None, None)
00515         c=inuse.back("Exit", "Ignore", name="Exit")
00516         c.event("EndDialog", "Exit")
00517         c=inuse.next("Ignore", "Retry", name="Ignore")
00518         c.event("EndDialog", "Ignore")
00519         c=inuse.cancel("Retry", "Exit", name="Retry")
00520         c.event("EndDialog","Retry")
00521 
00522         # See "Error Dialog". See "ICE20" for the required names of the controls.
00523         error = Dialog(db, "ErrorDlg",
00524                        50, 10, 330, 101,
00525                        65543,       # Error|Minimize|Modal|Visible
00526                        title,
00527                        "ErrorText", None, None)
00528         error.text("ErrorText", 50,9,280,48,3, "")
00529         #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
00530         error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
00531         error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
00532         error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
00533         error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
00534         error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
00535         error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
00536         error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
00537 
00538         #####################################################################
00539         # Global "Query Cancel" dialog
00540         cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
00541                         "No", "No", "No")
00542         cancel.text("Text", 48, 15, 194, 30, 3,
00543                     "Are you sure you want to cancel [ProductName] installation?")
00544         #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
00545         #               "py.ico", None, None)
00546         c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
00547         c.event("EndDialog", "Exit")
00548 
00549         c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
00550         c.event("EndDialog", "Return")
00551 
00552         #####################################################################
00553         # Global "Wait for costing" dialog
00554         costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
00555                          "Return", "Return", "Return")
00556         costing.text("Text", 48, 15, 194, 30, 3,
00557                      "Please wait while the installer finishes determining your disk space requirements.")
00558         c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
00559         c.event("EndDialog", "Exit")
00560 
00561         #####################################################################
00562         # Preparation dialog: no user input except cancellation
00563         prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
00564                         "Cancel", "Cancel", "Cancel")
00565         prep.text("Description", 15, 70, 320, 40, 0x30003,
00566                   "Please wait while the Installer prepares to guide you through the installation.")
00567         prep.title("Welcome to the [ProductName] Installer")
00568         c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...")
00569         c.mapping("ActionText", "Text")
00570         c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None)
00571         c.mapping("ActionData", "Text")
00572         prep.back("Back", None, active=0)
00573         prep.next("Next", None, active=0)
00574         c=prep.cancel("Cancel", None)
00575         c.event("SpawnDialog", "CancelDlg")
00576 
00577         #####################################################################
00578         # Feature (Python directory) selection
00579         seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title,
00580                         "Next", "Next", "Cancel")
00581         seldlg.title("Select Python Installations")
00582 
00583         seldlg.text("Hint", 15, 30, 300, 20, 3,
00584                     "Select the Python locations where %s should be installed."
00585                     % self.distribution.get_fullname())
00586 
00587         seldlg.back("< Back", None, active=0)
00588         c = seldlg.next("Next >", "Cancel")
00589         order = 1
00590         c.event("[TARGETDIR]", "[SourceDir]", ordering=order)
00591         for version in self.versions + [self.other_version]:
00592             order += 1
00593             c.event("[TARGETDIR]", "[TARGETDIR%s]" % version,
00594                     "FEATURE_SELECTED AND &Python%s=3" % version,
00595                     ordering=order)
00596         c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1)
00597         c.event("EndDialog", "Return", ordering=order + 2)
00598         c = seldlg.cancel("Cancel", "Features")
00599         c.event("SpawnDialog", "CancelDlg")
00600 
00601         c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3,
00602                            "FEATURE", None, "PathEdit", None)
00603         c.event("[FEATURE_SELECTED]", "1")
00604         ver = self.other_version
00605         install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver
00606         dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver
00607 
00608         c = seldlg.text("Other", 15, 200, 300, 15, 3,
00609                         "Provide an alternate Python location")
00610         c.condition("Enable", install_other_cond)
00611         c.condition("Show", install_other_cond)
00612         c.condition("Disable", dont_install_other_cond)
00613         c.condition("Hide", dont_install_other_cond)
00614 
00615         c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1,
00616                            "TARGETDIR" + ver, None, "Next", None)
00617         c.condition("Enable", install_other_cond)
00618         c.condition("Show", install_other_cond)
00619         c.condition("Disable", dont_install_other_cond)
00620         c.condition("Hide", dont_install_other_cond)
00621 
00622         #####################################################################
00623         # Disk cost
00624         cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
00625                         "OK", "OK", "OK", bitmap=False)
00626         cost.text("Title", 15, 6, 200, 15, 0x30003,
00627                   "{\DlgFontBold8}Disk Space Requirements")
00628         cost.text("Description", 20, 20, 280, 20, 0x30003,
00629                   "The disk space required for the installation of the selected features.")
00630         cost.text("Text", 20, 53, 330, 60, 3,
00631                   "The highlighted volumes (if any) do not have enough disk space "
00632               "available for the currently selected features.  You can either "
00633               "remove some files from the highlighted volumes, or choose to "
00634               "install less features onto local drive(s), or select different "
00635               "destination drive(s).")
00636         cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
00637                      None, "{120}{70}{70}{70}{70}", None, None)
00638         cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
00639 
00640         #####################################################################
00641         # WhichUsers Dialog. Only available on NT, and for privileged users.
00642         # This must be run before FindRelatedProducts, because that will
00643         # take into account whether the previous installation was per-user
00644         # or per-machine. We currently don't support going back to this
00645         # dialog after "Next" was selected; to support this, we would need to
00646         # find how to reset the ALLUSERS property, and how to re-run
00647         # FindRelatedProducts.
00648         # On Windows9x, the ALLUSERS property is ignored on the command line
00649         # and in the Property table, but installer fails according to the documentation
00650         # if a dialog attempts to set ALLUSERS.
00651         whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
00652                             "AdminInstall", "Next", "Cancel")
00653         whichusers.title("Select whether to install [ProductName] for all users of this computer.")
00654         # A radio group with two options: allusers, justme
00655         g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3,
00656                                   "WhichUsers", "", "Next")
00657         g.add("ALL", 0, 5, 150, 20, "Install for all users")
00658         g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
00659 
00660         whichusers.back("Back", None, active=0)
00661 
00662         c = whichusers.next("Next >", "Cancel")
00663         c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
00664         c.event("EndDialog", "Return", ordering = 2)
00665 
00666         c = whichusers.cancel("Cancel", "AdminInstall")
00667         c.event("SpawnDialog", "CancelDlg")
00668 
00669         #####################################################################
00670         # Installation Progress dialog (modeless)
00671         progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
00672                             "Cancel", "Cancel", "Cancel", bitmap=False)
00673         progress.text("Title", 20, 15, 200, 15, 0x30003,
00674                       "{\DlgFontBold8}[Progress1] [ProductName]")
00675         progress.text("Text", 35, 65, 300, 30, 3,
00676                       "Please wait while the Installer [Progress2] [ProductName]. "
00677                       "This may take several minutes.")
00678         progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
00679 
00680         c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
00681         c.mapping("ActionText", "Text")
00682 
00683         #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
00684         #c.mapping("ActionData", "Text")
00685 
00686         c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
00687                            None, "Progress done", None, None)
00688         c.mapping("SetProgress", "Progress")
00689 
00690         progress.back("< Back", "Next", active=False)
00691         progress.next("Next >", "Cancel", active=False)
00692         progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")
00693 
00694         ###################################################################
00695         # Maintenance type: repair/uninstall
00696         maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
00697                          "Next", "Next", "Cancel")
00698         maint.title("Welcome to the [ProductName] Setup Wizard")
00699         maint.text("BodyText", 15, 63, 330, 42, 3,
00700                    "Select whether you want to repair or remove [ProductName].")
00701         g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3,
00702                             "MaintenanceForm_Action", "", "Next")
00703         #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
00704         g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
00705         g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
00706 
00707         maint.back("< Back", None, active=False)
00708         c=maint.next("Finish", "Cancel")
00709         # Change installation: Change progress dialog to "Change", then ask
00710         # for feature selection
00711         #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
00712         #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
00713 
00714         # Reinstall: Change progress dialog to "Repair", then invoke reinstall
00715         # Also set list of reinstalled features to "ALL"
00716         c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
00717         c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6)
00718         c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
00719         c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)
00720 
00721         # Uninstall: Change progress to "Remove", then invoke uninstall
00722         # Also set list of removed features to "ALL"
00723         c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
00724         c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12)
00725         c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13)
00726         c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)
00727 
00728         # Close dialog when maintenance action scheduled
00729         c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
00730         #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
00731 
00732         maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")

Here is the call graph for this function:

Definition at line 138 of file bdist_msi.py.

00138 
00139     def finalize_options(self):
00140         self.set_undefined_options('bdist', ('skip_build', 'skip_build'))
00141 
00142         if self.bdist_dir is None:
00143             bdist_base = self.get_finalized_command('bdist').bdist_base
00144             self.bdist_dir = os.path.join(bdist_base, 'msi')
00145 
00146         short_version = get_python_version()
00147         if (not self.target_version) and self.distribution.has_ext_modules():
00148             self.target_version = short_version
00149 
00150         if self.target_version:
00151             self.versions = [self.target_version]
00152             if not self.skip_build and self.distribution.has_ext_modules()\
00153                and self.target_version != short_version:
00154                 raise DistutilsOptionError(
00155                       "target version can only be %s, or the '--skip-build'"
00156                       " option must be specified" % (short_version,))
00157         else:
00158             self.versions = list(self.all_versions)
00159 
00160         self.set_undefined_options('bdist',
00161                                    ('dist_dir', 'dist_dir'),
00162                                    ('plat_name', 'plat_name'),
00163                                    )
00164 
00165         if self.pre_install_script:
00166             raise DistutilsOptionError(
00167                   "the pre-install-script feature is not yet implemented")
00168 
00169         if self.install_script:
00170             for script in self.distribution.scripts:
00171                 if self.install_script == os.path.basename(script):
00172                     break
00173             else:
00174                 raise DistutilsOptionError(
00175                       "install_script '%s' not found in scripts"
00176                       % self.install_script)
00177         self.install_script_key = None

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 733 of file bdist_msi.py.

00733 
00734     def get_installer_filename(self, fullname):
00735         # Factored out to allow overriding in subclasses
00736         if self.target_version:
00737             base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name,
00738                                             self.target_version)
00739         else:
00740             base_name = "%s.%s.msi" % (fullname, self.plat_name)
00741         installer_name = os.path.join(self.dist_dir, base_name)
00742         return installer_name

Here is the caller graph for this function:

Definition at line 125 of file bdist_msi.py.

00125 
00126     def initialize_options(self):
00127         self.bdist_dir = None
00128         self.plat_name = None
00129         self.keep_temp = 0
00130         self.no_target_compile = 0
00131         self.no_target_optimize = 0
00132         self.target_version = None
00133         self.dist_dir = None
00134         self.skip_build = None
00135         self.install_script = None
00136         self.pre_install_script = None
00137         self.versions = None

Definition at line 178 of file bdist_msi.py.

00178 
00179     def run(self):
00180         if not self.skip_build:
00181             self.run_command('build')
00182 
00183         install = self.reinitialize_command('install', reinit_subcommands=1)
00184         install.prefix = self.bdist_dir
00185         install.skip_build = self.skip_build
00186         install.warn_dir = 0
00187 
00188         install_lib = self.reinitialize_command('install_lib')
00189         # we do not want to include pyc or pyo files
00190         install_lib.compile = 0
00191         install_lib.optimize = 0
00192 
00193         if self.distribution.has_ext_modules():
00194             # If we are building an installer for a Python version other
00195             # than the one we are currently running, then we need to ensure
00196             # our build_lib reflects the other Python version rather than ours.
00197             # Note that for target_version!=sys.version, we must have skipped the
00198             # build step, so there is no issue with enforcing the build of this
00199             # version.
00200             target_version = self.target_version
00201             if not target_version:
00202                 assert self.skip_build, "Should have already checked this"
00203                 target_version = sys.version[0:3]
00204             plat_specifier = ".%s-%s" % (self.plat_name, target_version)
00205             build = self.get_finalized_command('build')
00206             build.build_lib = os.path.join(build.build_base,
00207                                            'lib' + plat_specifier)
00208 
00209         log.info("installing to %s", self.bdist_dir)
00210         install.ensure_finalized()
00211 
00212         # avoid warning of 'install_lib' about installing
00213         # into a directory not in sys.path
00214         sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB'))
00215 
00216         install.run()
00217 
00218         del sys.path[0]
00219 
00220         self.mkpath(self.dist_dir)
00221         fullname = self.distribution.get_fullname()
00222         installer_name = self.get_installer_filename(fullname)
00223         installer_name = os.path.abspath(installer_name)
00224         if os.path.exists(installer_name): os.unlink(installer_name)
00225 
00226         metadata = self.distribution.metadata
00227         author = metadata.author
00228         if not author:
00229             author = metadata.maintainer
00230         if not author:
00231             author = "UNKNOWN"
00232         version = metadata.get_version()
00233         # ProductVersion must be strictly numeric
00234         # XXX need to deal with prerelease versions
00235         sversion = "%d.%d.%d" % StrictVersion(version).version
00236         # Prefix ProductName with Python x.y, so that
00237         # it sorts together with the other Python packages
00238         # in Add-Remove-Programs (APR)
00239         fullname = self.distribution.get_fullname()
00240         if self.target_version:
00241             product_name = "Python %s %s" % (self.target_version, fullname)
00242         else:
00243             product_name = "Python %s" % (fullname)
00244         self.db = msilib.init_database(installer_name, schema,
00245                 product_name, msilib.gen_uuid(),
00246                 sversion, author)
00247         msilib.add_tables(self.db, sequence)
00248         props = [('DistVersion', version)]
00249         email = metadata.author_email or metadata.maintainer_email
00250         if email:
00251             props.append(("ARPCONTACT", email))
00252         if metadata.url:
00253             props.append(("ARPURLINFOABOUT", metadata.url))
00254         if props:
00255             add_data(self.db, 'Property', props)
00256 
00257         self.add_find_python()
00258         self.add_files()
00259         self.add_scripts()
00260         self.add_ui()
00261         self.db.Commit()
00262 
00263         if hasattr(self.distribution, 'dist_files'):
00264             tup = 'bdist_msi', self.target_version or 'any', fullname
00265             self.distribution.dist_files.append(tup)
00266 
00267         if not self.keep_temp:
00268             remove_tree(self.bdist_dir, dry_run=self.dry_run)

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Initial value:
['2.0', '2.1', '2.2', '2.3', '2.4',
                    '2.5', '2.6', '2.7', '2.8', '2.9',
                    '3.0', '3.1', '3.2', '3.3', '3.4',
                    '3.5', '3.6', '3.7', '3.8', '3.9']

Definition at line 119 of file bdist_msi.py.

Definition at line 126 of file bdist_msi.py.

Initial value:
['keep-temp', 'no-target-compile', 'no-target-optimize',
                       'skip-build']

Definition at line 116 of file bdist_msi.py.

Definition at line 243 of file bdist_msi.py.

string distutils.command.bdist_msi.bdist_msi.description = "create a Microsoft Installer (.msi) binary distribution" [static]

Definition at line 85 of file bdist_msi.py.

Definition at line 132 of file bdist_msi.py.

Definition at line 134 of file bdist_msi.py.

Definition at line 176 of file bdist_msi.py.

Definition at line 128 of file bdist_msi.py.

Definition at line 129 of file bdist_msi.py.

Definition at line 130 of file bdist_msi.py.

Definition at line 123 of file bdist_msi.py.

Definition at line 127 of file bdist_msi.py.

Definition at line 135 of file bdist_msi.py.

Definition at line 133 of file bdist_msi.py.

Definition at line 131 of file bdist_msi.py.

Initial value:
[('bdist-dir=', None,
                     "temporary directory for creating the distribution"),
                    ('plat-name=', 'p',
                     "platform name to embed in generated filenames "
                     "(default: %s)" % get_platform()),
                    ('keep-temp', 'k',
                     "keep the pseudo-installation tree around after " +
                     "creating the distribution archive"),
                    ('target-version=', None,
                     "require a specific python version" +
                     " on the target system"),
                    ('no-target-compile', 'c',
                     "do not compile .py to .pyc on the target system"),
                    ('no-target-optimize', 'o',
                     "do not compile .py to .pyo (optimized)"
                     "on the target system"),
                    ('dist-dir=', 'd',
                     "directory to put final built distributions in"),
                    ('skip-build', None,
                     "skip rebuilding everything (for testing/debugging)"),
                    ('install-script=', None,
                     "basename of installation script to be run after"
                     "installation or before deinstallation"),
                    ('pre-install-script=', None,
                     "Fully qualified filename of a script to be run before "
                     "any files are installed.  This script need not be in the "
                     "distribution"),
                   ]

Definition at line 87 of file bdist_msi.py.

Definition at line 136 of file bdist_msi.py.


The documentation for this class was generated from the following file: