[Python-checkins] python/nondist/sandbox/msi msi.py,1.18,1.19

loewis at users.sourceforge.net loewis at users.sourceforge.net
Sun Aug 1 12:02:17 CEST 2004


Update of /cvsroot/python/python/nondist/sandbox/msi
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24627

Modified Files:
	msi.py 
Log Message:
Refer to MSDN in many places.


Index: msi.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/msi/msi.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** msi.py	27 Jul 2004 16:36:21 -0000	1.18
--- msi.py	1 Aug 2004 10:02:14 -0000	1.19
***************
*** 1,4 ****
--- 1,5 ----
  # Python MSI Generator
  # (C) 2003 Martin v. Loewis
+ # See "FOO" in comments refers to MSDN sections with the title FOO.
  import msilib, schema, sequence, os, glob, time
  from msilib import Feature, CAB, Directory, Dialog, Binary, add_data
***************
*** 32,41 ****
  short_version = major+"."+minor
  
! # This should never change
  upgrade_code_alpha='{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
  upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
  
! # This should be extended for each Python release
! # Alpha releases have their own product code
  product_codes = {
      '2.3.2'  : "{3ad0c9ed-7e5e-478c-b539-5cc3a2f8772a}",
--- 33,50 ----
  short_version = major+"."+minor
  
! # This should never change. The UpgradeCode of this package can be
! # used in the Upgrade table of future packages to make the future
! # package replace this one. See "UpgradeCode Property".
  upgrade_code_alpha='{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
  upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
  
! # This should be extended for each Python release.
! # The product code must change whenever the name of the MSI file
! # changes, and when new component codes are issued for existing
! # components. See "Changing the Product Code". As we change the
! # component codes with every build, we need a new product code
! # each time. For intermediate (alpha) releases, they are automatically
! # generated. For official releases, we record the product codes,
! # so people can refer to them.
  product_codes = {
      '2.3.2'  : "{3ad0c9ed-7e5e-478c-b539-5cc3a2f8772a}",
***************
*** 95,98 ****
--- 104,109 ----
  
  def build_database():
+     """Generate an empty database, with just the schema and the
+     Summary information stream."""
      if alpha:
          cv = "%s.%s.%s" % (major, minor, release)
***************
*** 101,104 ****
--- 112,118 ----
          cv = current_version
          uc = upgrade_code
+     # schema represents the installer 2.0 database schema.
+     # sequence is the set of standard sequences
+     # (ui/execute, admin/advt/install)
      db = msilib.init_database("python%s.msi" % full_current_version, schema,
                            ProductName="Python "+full_current_version,
***************
*** 107,110 ****
--- 121,129 ----
                    Manufacturer=u"Martin v. L\xf6wis")
      msilib.add_tables(db, sequence)
+     # We cannot set ALLUSERS in the property table, as this cannot be
+     # reset if the user choses a per-user installation. Instead, we
+     # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages
+     # this property, and when the execution starts, ALLUSERS is set
+     # accordingly.
      add_data(db, "Property", [("UpgradeCode", uc),
                                ("WhichUsers", "ALL"),
***************
*** 114,124 ****
  
  def remove_old_versions(db):
      start = "%s.%s.0" % (major, minor)
      migrate_features = 1
      if alpha:
          add_data(db, "Upgrade",
              [(upgrade_code_alpha, start,  
!               "%s.%s.%s" % (major, minor, release), None, migrate_features, 
!               None, "REMOVEOLDALPHA")])
          props = "REMOVEOLDALPHA"
      else:
--- 133,154 ----
  
  def remove_old_versions(db):
+     "Fill the upgrade table."
      start = "%s.%s.0" % (major, minor)
+     # This requests that feature selection states of an older
+     # installation should be forwarded into this one. It currently
+     # does not work if the older installation was per-machine
+     # and the current installation starts as per-user.
      migrate_features = 1
+     # See "Upgrade Table". We remove releases with the same major and
+     # minor version. For an alpha, we remove all earlier alphas. For
+     # a release, we remove all alphas, and all earlier releases.
      if alpha:
          add_data(db, "Upgrade",
              [(upgrade_code_alpha, start,  
!               "%s.%s.%s" % (major, minor, release),
!               None,                     # Ignore language
!               migrate_features, 
!               None,                     # Migrate ALL features
!               "REMOVEOLDALPHA")])
          props = "REMOVEOLDALPHA"
      else:
***************
*** 129,137 ****
                None, migrate_features, None, "REMOVEOLDALPHA")])
          props = "REMOVEOLDALPHA;REMOVEOLDVERSION"
      add_data(db, "Property", [("SecureCustomProperties", props)])
  
- 
  class PyDialog(Dialog):
      def __init__(self, *args, **kw):
          Dialog.__init__(self, *args)
          ruler = self.h - 36
--- 159,174 ----
                None, migrate_features, None, "REMOVEOLDALPHA")])
          props = "REMOVEOLDALPHA;REMOVEOLDVERSION"
+     # Installer collects the product codes of the earlier releases in
+     # these properties. In order to allow modification of the properties,
+     # they must be declared as secure. See "SecureCustomProperties Property"
      add_data(db, "Property", [("SecureCustomProperties", props)])
  
  class PyDialog(Dialog):
+     """Dialog class with a fixed layout: controls at the top, then a ruler,
+     then a list of buttons: back, next, cancel. Optionally a bitmap at the
+     left."""
      def __init__(self, *args, **kw):
+         """Dialog(database, name, x, y, w, h, attributes, title, first,
+         default, cancel, bitmap=true)"""
          Dialog.__init__(self, *args)
          ruler = self.h - 36
***************
*** 142,170 ****
  
      def title(self, title):
!         self.text("Title", 135, 10, 220, 60, 196611,
                    r"{\VerdanaBold10}%s" % title)
  
      def back(self, title, next, name = "Back", active = 1):
          if active:
!             flags = 3
          else:
!             flags = 1
          return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
  
      def cancel(self, title, next, name = "Cancel", active = 1):
          if active:
!             flags = 3
          else:
!             flags = 1
          return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
  
      def next(self, title, next, name = "Next", active = 1):
          if active:
!             flags = 3
          else:
!             flags = 1
          return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
  
      def xbutton(self, name, title, next, xpos):
          return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
  
--- 179,227 ----
  
      def title(self, title):
!         "Set the title text of the dialog at the top."
!         # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix,
!         # text, in VerdanaBold10
!         self.text("Title", 135, 10, 220, 60, 0x30003,
                    r"{\VerdanaBold10}%s" % title)
  
      def back(self, title, next, name = "Back", active = 1):
+         """Add a back button with a given title, the tab-next button,
+         its name in the Control table, possibly initially disabled.
+ 
+         Return the button, so that events can be associated"""
          if active:
!             flags = 3 # Visible|Enabled
          else:
!             flags = 1 # Visible
          return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next)
  
      def cancel(self, title, next, name = "Cancel", active = 1):
+         """Add a cancel button with a given title, the tab-next button,
+         its name in the Control table, possibly initially disabled.
+ 
+         Return the button, so that events can be associated"""
          if active:
!             flags = 3 # Visible|Enabled
          else:
!             flags = 1 # Visible
          return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next)
  
      def next(self, title, next, name = "Next", active = 1):
+         """Add a Next button with a given title, the tab-next button,
+         its name in the Control table, possibly initially disabled.
+ 
+         Return the button, so that events can be associated"""
          if active:
!             flags = 3 # Visible|Enabled
          else:
!             flags = 1 # Visible
          return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next)
  
      def xbutton(self, name, title, next, xpos):
+         """Add a button with a given title, the tab-next button,
+         its name in the Control table, giving its x position; the
+         y-position is aligned with the other buttons.
+ 
+         Return the button, so that events can be associated"""
          return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next)
  
***************
*** 175,179 ****
      title = "[ProductName] Setup"
  
!     # Dialog styles
      modal = 3      # visible | modal
      modeless = 1   # visible
--- 232,236 ----
      title = "[ProductName] Setup"
  
!     # see "Dialog Style Bits"
      modal = 3      # visible | modal
      modeless = 1   # visible
***************
*** 202,205 ****
--- 259,263 ----
      """)
      add_data(db, "Binary", [("Script", msilib.Binary("inst.vbs"))])
+     # See "Custom Action Type 6"
      add_data(db, "CustomAction", [("CheckDir", 6, "Script", "CheckDir")])
      os.unlink("inst.vbs")
***************
*** 208,212 ****
--- 266,272 ----
      # 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
***************
*** 214,218 ****
                ("MaintenanceForm_Action", "Repair")])
  
!     # Fonts
      add_data(db, "TextStyle",
               [("DlgFont8", "Tahoma", 9, None, 0),
--- 274,278 ----
                ("MaintenanceForm_Action", "Repair")])
  
!     # Fonts, see "TextStyle Table"
      add_data(db, "TextStyle",
               [("DlgFont8", "Tahoma", 9, None, 0),
***************
*** 221,227 ****
               ])
  
!     # Custom actions
      add_data(db, "CustomAction", [
          # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
          ("InitialTargetDir", 307, "TARGETDIR",
           "[WindowsVolume]Python%s%s" % (major, minor)),
--- 281,289 ----
               ])
  
!     # See "CustomAction Table"
      add_data(db, "CustomAction", [
          # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
+         # See "Custom Action Type 51",
+         # "Custom Action Execution Scheduling Options"
          ("InitialTargetDir", 307, "TARGETDIR",
           "[WindowsVolume]Python%s%s" % (major, minor)),
***************
*** 230,234 ****
          ])
  
!     # UI Sequences
      add_data(db, "InstallUISequence",
               [("PrepareDlg", None, 140),
--- 292,297 ----
          ])
  
!     # 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", None, 140),
***************
*** 238,242 ****
                ("SetDLLDirToTarget", 'DLLDIR="" and not Privileged', 752),
                ("SelectDirectoryDlg", "Not Installed", 1230),
!               # XXX notyet
                #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
                ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
--- 301,305 ----
                ("SetDLLDirToTarget", 'DLLDIR="" and not Privileged', 752),
                ("SelectDirectoryDlg", "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),
***************
*** 265,271 ****
      fatal.back("< Back", "Finish", active = 0)
      fatal.cancel("Cancel", "Back", active = 0)
!     fatal.text("Description1", 135, 70, 220, 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", 135, 155, 220, 20, 196611,
                 "Click the Finish button to exit the Installer.")
      c=fatal.next("Finish", "Cancel", name="Finish")
--- 328,334 ----
      fatal.back("< Back", "Finish", active = 0)
      fatal.cancel("Cancel", "Back", active = 0)
!     fatal.text("Description1", 135, 70, 220, 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", 135, 155, 220, 20, 0x30003,
                 "Click the Finish button to exit the Installer.")
      c=fatal.next("Finish", "Cancel", name="Finish")
***************
*** 277,284 ****
      user_exit.back("< Back", "Finish", active = 0)
      user_exit.cancel("Cancel", "Back", active = 0)
!     user_exit.text("Description1", 135, 70, 220, 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", 135, 155, 220, 20, 196611,
                 "Click the Finish button to exit the Installer.")
      c = user_exit.next("Finish", "Cancel", name="Finish")
--- 340,347 ----
      user_exit.back("< Back", "Finish", active = 0)
      user_exit.cancel("Cancel", "Back", active = 0)
!     user_exit.text("Description1", 135, 70, 220, 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", 135, 155, 220, 20, 0x30003,
                 "Click the Finish button to exit the Installer.")
      c = user_exit.next("Finish", "Cancel", name="Finish")
***************
*** 290,294 ****
      exit_dialog.back("< Back", "Finish", active = 0)
      exit_dialog.cancel("Cancel", "Back", active = 0)
!     exit_dialog.text("Description", 135, 115, 220, 20, 196611,
                 "Click the Finish button to exit the Installer.")
      c = exit_dialog.next("Finish", "Cancel", name="Finish")
--- 353,357 ----
      exit_dialog.back("< Back", "Finish", active = 0)
      exit_dialog.cancel("Cancel", "Back", active = 0)
!     exit_dialog.text("Description", 135, 115, 220, 20, 0x30003,
                 "Click the Finish button to exit the Installer.")
      c = exit_dialog.next("Finish", "Cancel", name="Finish")
***************
*** 297,305 ****
      #####################################################################
      # Required dialog: FilesInUse, ErrorDlg
!     inuse = PyDialog(db, "FilesInUse", x, y, w, h, 19, title,
                       "Retry", "Retry", "Retry", bitmap=False)
!     inuse.text("Title", 15, 6, 200, 15, 196611,
                 r"{\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,
--- 360,371 ----
      #####################################################################
      # 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,
***************
*** 314,318 ****
      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, "")
--- 380,389 ----
      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, "")
***************
*** 355,364 ****
      prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
                      "Cancel", "Cancel", "Cancel")
!     prep.text("Description", 135, 70, 220, 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", 135, 110, 220, 20, 196611, "Pondering...")
      c.mapping("ActionText", "Text")
!     c=prep.text("ActionData", 135, 135, 220, 30, 196611, None)
      c.mapping("ActionData", "Text")
      prep.back("Back", None, active=0)
--- 426,435 ----
      prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
                      "Cancel", "Cancel", "Cancel")
!     prep.text("Description", 135, 70, 220, 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", 135, 110, 220, 20, 0x30003, "Pondering...")
      c.mapping("ActionText", "Text")
!     c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None)
      c.mapping("ActionData", "Text")
      prep.back("Back", None, active=0)
***************
*** 371,375 ****
                      "Next", "Next", "Cancel")
      seldlg.title("Select Destination Directory")
!     seldlg.text("Description", 135, 50, 220, 40, 196611,
                 "Please select a directory for the [ProductName] files.")
  
--- 442,446 ----
                      "Next", "Next", "Cancel")
      seldlg.title("Select Destination Directory")
!     seldlg.text("Description", 135, 50, 220, 40, 0x30003,
                 "Please select a directory for the [ProductName] files.")
  
***************
*** 400,404 ****
                          title, "Tree", "Next", "Cancel")
      features.title("Customize [ProductName]")
!     features.text("Description", 135, 35, 220, 15, 196611,
                    "Select the way you want features to be installed.")
      features.text("Text", 135,45,220,30, 3,
--- 471,475 ----
                          title, "Tree", "Next", "Cancel")
      features.title("Customize [ProductName]")
!     features.text("Description", 135, 35, 220, 15, 0x30003,
                    "Select the way you want features to be installed.")
      features.text("Text", 135,45,220,30, 3,
***************
*** 446,452 ****
      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,
--- 517,523 ----
      cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
                      "OK", "OK", "OK", bitmap=False)
!     cost.text("Title", 15, 6, 200, 15, 0x30003,
                "{\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,
***************
*** 465,476 ****
                          "OK", "OK", "OK")
      advanced.title("Advanced Options")
      g = advanced.radiogroup("AdminInstall", 135, 60, 160, 50, 3,
                              "WhichUsers", "", "OK")
      # ALLUSERS should not be tempered with on W9x
      g.condition("Hide", "Windows9x or NOT Privileged") 
      g.add("ALL", 0, 5, 150, 20, "Install for all users")
      g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
  
!     # Alternative texts if AdminInstall is not available
      c=advanced.text("Unprivileged", 135, 90, 160, 50, 3,
                      "Installing Python for all users is not possible, because you lack privileges. Python will be installed for you only.")
--- 536,549 ----
                          "OK", "OK", "OK")
      advanced.title("Advanced Options")
+     # A radio group with two options: allusers, justme
      g = advanced.radiogroup("AdminInstall", 135, 60, 160, 50, 3,
                              "WhichUsers", "", "OK")
      # ALLUSERS should not be tempered with on W9x
+     # See "ControlCondition Table"
      g.condition("Hide", "Windows9x or NOT Privileged") 
      g.add("ALL", 0, 5, 150, 20, "Install for all users")
      g.add("JUSTME", 0, 25, 150, 20, "Install just for me")
  
!     # Alternative texts if privilged install is not available
      c=advanced.text("Unprivileged", 135, 90, 160, 50, 3,
                      "Installing Python for all users is not possible, because you lack privileges. Python will be installed for you only.")
***************
*** 481,484 ****
--- 554,560 ----
  
      c = advanced.cancel("Ok", "AdminInstall", name="OK")
+     # See "ControlEvent Table". Parameters are the event, the parameter
+     # to the action, the condition for the event, and optionally the order
+     # of events.
      c.event("DoAction", "SetDLLDirToTarget", 'WhichUsers="JUSTME"', 1)
      c.event("DoAction", "SetDLLDirToSystem32", 'WhichUsers="ALL" and (Windows9x or Privileged)', 2)
***************
*** 502,506 ****
      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,
--- 578,582 ----
      progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
                          "Cancel", "Cancel", "Cancel", bitmap=False)
!     progress.text("Title", 20, 15, 200, 15, 0x30003,
                    "{\DlgFontBold8}[Progress1] [ProductName]")
      progress.text("Text", 35, 65, 300, 30, 3,
***************
*** 556,559 ****
--- 632,639 ----
      
  
+ # See "Feature Table". The feature level is 1 for all features,
+ # and the feature attributes are 0 for the DefaultFeature, and
+ # FollowParent for all other features. The numbers are the Display
+ # column.
  def add_features(db):
      global default_feature, tcltk, htmlfiles, tools, testsuite, ext_feature
***************
*** 597,600 ****
--- 677,682 ----
             installer.FileVersion("msvcr71.dll", 1)
  
+ # See "File Table", "Component Table", "Directory Table",
+ # "FeatureComponents Table"
  def add_files(db):
      cab = CAB("python")
***************
*** 609,618 ****
      root.add_file("NEWS.txt", src="Misc/NEWS")
      root.add_file("LICENSE.txt", src="LICENSE")
!     # msidbComponentAttributesSharedDllRefCount = 8
!     root.start_component("python.exe", flags = 8, keyfile="python.exe")
      root.add_file("PCBuild/python.exe")
!     root.start_component("pythonw.exe", flags = 8, keyfile="pythonw.exe")
      root.add_file("PCBuild/pythonw.exe")
  
      dlldir = Directory(db, cab, root, srcdir, "DLLDIR", ".")
      pydll = "python%s%s.dll" % (major, minor)
--- 691,700 ----
      root.add_file("NEWS.txt", src="Misc/NEWS")
      root.add_file("LICENSE.txt", src="LICENSE")
!     root.start_component("python.exe", keyfile="python.exe")
      root.add_file("PCBuild/python.exe")
!     root.start_component("pythonw.exe", keyfile="pythonw.exe")
      root.add_file("PCBuild/pythonw.exe")
  
+     # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table"
      dlldir = Directory(db, cab, root, srcdir, "DLLDIR", ".")
      pydll = "python%s%s.dll" % (major, minor)
***************
*** 651,654 ****
--- 733,737 ----
          files += lib.glob("*.pyw")
          if files:
+             # Add an entry to the RemoveFile table to remove bytecode files.
              lib.remove_pyc()
          if dir=='test' and parent.physical=='Lib':
***************
*** 760,763 ****
--- 843,847 ----
          os.unlink(f)
  
+ # See "Registry Table", "Component Table"
  def add_registry(db):
      # File extensions, associated with the REGISTRY.def component
***************
*** 766,769 ****
--- 850,854 ----
      # -1 for Root specifies "dependent on ALLUSERS property"
      add_data(db, "Component",
+              # msidbComponentAttributesRegistryKeyPath = 4
               [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", 4, None,
                 "InstallPath"),
***************
*** 772,775 ****
--- 857,861 ----
                ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", 4,
                 "&%s <> 2" % ext_feature.id, "py.IDLE")])
+     # See "FeatureComponents Table"
      add_data(db, "FeatureComponents",
               [(default_feature.id, "REGISTRY"),
***************
*** 839,843 ****
                 "", r"[TARGETDIR]Python.exe", "REGISTRY.def")
                ])
!     # Shortcuts
      add_data(db, "Directory",
               [("ProgramMenuFolder", "TARGETDIR", "."),
--- 925,929 ----
                 "", r"[TARGETDIR]Python.exe", "REGISTRY.def")
                ])
!     # Shortcuts, see "Shortcut Table"
      add_data(db, "Directory",
               [("ProgramMenuFolder", "TARGETDIR", "."),



More information about the Python-checkins mailing list