Back to index

python3.2  3.2.2
Classes | Functions | Variables
msi Namespace Reference

Classes

class  PyDialog
class  PyDirectory

Functions

def build_mingw_lib
def build_database
def remove_old_versions
def add_ui
def add_features
def extract_msvcr90
def generate_license
def add_files
def add_registry
def build_pdbzip
def merge

Variables

int snapshot = 1
int testpackage = 0
tuple srcdir = os.path.abspath("../..")
 full_current_version = None
 have_tcl = True
string PCBUILD = "PCbuild"
string MSVCR = "90"
 certname = None
 pdbzip = True
tuple lines = open(srcdir + "/Include/patchlevel.h")
 major = minormicrolevelserialNone
dictionary levels
tuple l = l.split()
string short_version = "."
int FIELD3 = 1000
string current_version = "%s.%d"
string upgrade_code_snapshot = '{92A24481-3ECB-40FC-8836-04B7966EC0D5}'
string upgrade_code = '{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'
string upgrade_code_64 = '{6A965A0C-6EE6-4E3A-9983-3263F56311EC}'
tuple product_code = msilib.gen_uuid()
list extensions
dictionary pythondll_uuid
string docfile = ""
tuple lib_file = os.path.join(srcdir, PCBUILD, "python%s%s.lib" % (major, minor))
tuple def_file = os.path.join(srcdir, PCBUILD, "python%s%s.def" % (major, minor))
string dll_file = "python%s%s.dll"
tuple mingw_lib = os.path.join(srcdir, PCBUILD, "libpython%s%s.a" % (major, minor))
tuple have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib)
tuple dll_path = os.path.join(srcdir, PCBUILD, dll_file)
tuple digit = hex((int(product_code[-2],16)+1)%16)
string ext = 'px'
string testprefix = 'x'
string SystemFolderName = "[System64Folder]"
int registry_component = 4
string sys32cond = "(Windows9x or (Privileged and ALLUSERS))"
tuple mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules")
list modules = ["Microsoft_VC90_CRT_x86_x64.msm", "policy_9_0_Microsoft_VC90_CRT_x86_x64.msm"]

Function Documentation

def msi.add_features (   db)

Definition at line 823 of file msi.py.

00823 
00824 def add_features(db):
00825     # feature attributes:
00826     # msidbFeatureAttributesFollowParent == 2
00827     # msidbFeatureAttributesDisallowAdvertise == 8
00828     # Features that need to be installed with together with the main feature
00829     # (i.e. additional Python libraries) need to follow the parent feature.
00830     # Features that have no advertisement trigger (e.g. the test suite)
00831     # must not support advertisement
00832     global default_feature, tcltk, htmlfiles, tools, testsuite, ext_feature, private_crt
00833     default_feature = Feature(db, "DefaultFeature", "Python",
00834                               "Python Interpreter and Libraries",
00835                               1, directory = "TARGETDIR")
00836     shared_crt = Feature(db, "SharedCRT", "MSVCRT", "C Run-Time (system-wide)", 0,
00837                          level=0)
00838     private_crt = Feature(db, "PrivateCRT", "MSVCRT", "C Run-Time (private)", 0,
00839                           level=0)
00840     add_data(db, "Condition", [("SharedCRT", 1, sys32cond),
00841                                ("PrivateCRT", 1, "not "+sys32cond)])
00842     # We don't support advertisement of extensions
00843     ext_feature = Feature(db, "Extensions", "Register Extensions",
00844                           "Make this Python installation the default Python installation", 3,
00845                          parent = default_feature, attributes=2|8)
00846     if have_tcl:
00847         tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5,
00848                     parent = default_feature, attributes=2)
00849     htmlfiles = Feature(db, "Documentation", "Documentation",
00850                         "Python HTMLHelp File", 7, parent = default_feature)
00851     tools = Feature(db, "Tools", "Utility Scripts",
00852                     "Python utility scripts (Tools/", 9,
00853                     parent = default_feature, attributes=2)
00854     testsuite = Feature(db, "Testsuite", "Test suite",
00855                         "Python test suite (Lib/test/)", 11,
00856                         parent = default_feature, attributes=2|8)

Here is the call graph for this function:

Here is the caller graph for this function:

def msi.add_files (   db)

Definition at line 916 of file msi.py.

00916 
00917 def add_files(db):
00918     cab = CAB("python")
00919     tmpfiles = []
00920     # Add all executables, icons, text files into the TARGETDIR component
00921     root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir")
00922     default_feature.set_current()
00923     if not msilib.Win64:
00924         root.add_file("%s/w9xpopen.exe" % PCBUILD)
00925     root.add_file("README.txt", src="README")
00926     root.add_file("NEWS.txt", src="Misc/NEWS")
00927     generate_license()
00928     root.add_file("LICENSE.txt", src=os.path.abspath("LICENSE.txt"))
00929     root.start_component("python.exe", keyfile="python.exe")
00930     root.add_file("%s/python.exe" % PCBUILD)
00931     root.start_component("pythonw.exe", keyfile="pythonw.exe")
00932     root.add_file("%s/pythonw.exe" % PCBUILD)
00933 
00934     # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table"
00935     dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".")
00936 
00937     pydll = "python%s%s.dll" % (major, minor)
00938     pydllsrc = os.path.join(srcdir, PCBUILD, pydll)
00939     dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid)
00940     installer = msilib.MakeInstaller()
00941     pyversion = installer.FileVersion(pydllsrc, 0)
00942     if not snapshot:
00943         # For releases, the Python DLL has the same version as the
00944         # installer package.
00945         assert pyversion.split(".")[:3] == current_version.split(".")
00946     dlldir.add_file("%s/python%s%s.dll" % (PCBUILD, major, minor),
00947                     version=pyversion,
00948                     language=installer.FileVersion(pydllsrc, 1))
00949     DLLs = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs")
00950 
00951     # msvcr90.dll: Need to place the DLL and the manifest into the root directory,
00952     # plus another copy of the manifest in the DLLs directory, with the manifest
00953     # pointing to the root directory
00954     root.start_component("msvcr90", feature=private_crt)
00955     # Results are ID,keyword pairs
00956     manifest, crtdll = extract_msvcr90()
00957     root.add_file(manifest[0], **manifest[1])
00958     root.add_file(crtdll[0], **crtdll[1])
00959     # Copy the manifest
00960     # Actually, don't do that anymore - no DLL in DLLs should have a manifest
00961     # dependency on msvcr90.dll anymore, so this should not be necessary
00962     #manifest_dlls = manifest[0]+".root"
00963     #open(manifest_dlls, "w").write(open(manifest[1]['src']).read().replace("msvcr","../msvcr"))
00964     #DLLs.start_component("msvcr90_dlls", feature=private_crt)
00965     #DLLs.add_file(manifest[0], src=os.path.abspath(manifest_dlls))
00966 
00967     # Now start the main component for the DLLs directory;
00968     # no regular files have been added to the directory yet.
00969     DLLs.start_component()
00970 
00971     # Check if _ctypes.pyd exists
00972     have_ctypes = os.path.exists(srcdir+"/%s/_ctypes.pyd" % PCBUILD)
00973     if not have_ctypes:
00974         print("WARNING: _ctypes.pyd not found, ctypes will not be included")
00975         extensions.remove("_ctypes.pyd")
00976 
00977     # Add all .py files in Lib, except tkinter, test
00978     dirs = []
00979     pydirs = [(root,"Lib")]
00980     while pydirs:
00981         # Commit every now and then, or else installer will complain
00982         db.Commit()
00983         parent, dir = pydirs.pop()
00984         if dir == ".svn" or dir == '__pycache__' or dir.startswith("plat-"):
00985             continue
00986         elif dir in ["tkinter", "idlelib", "Icons"]:
00987             if not have_tcl:
00988                 continue
00989             tcltk.set_current()
00990         elif dir in ['test', 'tests', 'data', 'output']:
00991             # test: Lib, Lib/email, Lib/ctypes, Lib/sqlite3
00992             # tests: Lib/distutils
00993             # data: Lib/email/test
00994             # output: Lib/test
00995             testsuite.set_current()
00996         elif not have_ctypes and dir == "ctypes":
00997             continue
00998         else:
00999             default_feature.set_current()
01000         lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir))
01001         # Add additional files
01002         dirs.append(lib)
01003         lib.glob("*.txt")
01004         if dir=='site-packages':
01005             lib.add_file("README.txt", src="README")
01006             continue
01007         files = lib.glob("*.py")
01008         files += lib.glob("*.pyw")
01009         if files:
01010             # Add an entry to the RemoveFile table to remove bytecode files.
01011             lib.remove_pyc()
01012         # package READMEs if present
01013         lib.glob("README")
01014         if dir=='Lib':
01015             lib.add_file('wsgiref.egg-info')
01016         if dir=='test' and parent.physical=='Lib':
01017             lib.add_file("185test.db")
01018             lib.add_file("audiotest.au")
01019             lib.add_file("sgml_input.html")
01020             lib.add_file("testtar.tar")
01021             lib.add_file("test_difflib_expect.html")
01022             lib.add_file("check_soundcard.vbs")
01023             lib.add_file("empty.vbs")
01024             lib.add_file("Sine-1000Hz-300ms.aif")
01025             lib.glob("*.uue")
01026             lib.glob("*.pem")
01027             lib.glob("*.pck")
01028             lib.glob("cfgparser.*")
01029             lib.add_file("zip_cp437_header.zip")
01030             lib.add_file("zipdir.zip")
01031         if dir=='capath':
01032             lib.glob("*.0")
01033         if dir=='tests' and parent.physical=='distutils':
01034             lib.add_file("Setup.sample")
01035         if dir=='decimaltestdata':
01036             lib.glob("*.decTest")
01037         if dir=='xmltestdata':
01038             lib.glob("*.xml")
01039             lib.add_file("test.xml.out")
01040         if dir=='output':
01041             lib.glob("test_*")
01042         if dir=='sndhdrdata':
01043             lib.glob("sndhdr.*")
01044         if dir=='idlelib':
01045             lib.glob("*.def")
01046             lib.add_file("idle.bat")
01047             lib.add_file("ChangeLog")
01048         if dir=="Icons":
01049             lib.glob("*.gif")
01050             lib.add_file("idle.icns")
01051         if dir=="command" and parent.physical=="distutils":
01052             lib.glob("wininst*.exe")
01053             lib.add_file("command_template")
01054         if dir=="lib2to3":
01055             lib.removefile("pickle", "*.pickle")
01056         if dir=="macholib":
01057             lib.add_file("README.ctypes")
01058             lib.glob("fetch_macholib*")
01059         if dir=='turtledemo':
01060             lib.add_file("turtle.cfg")
01061         if dir=="pydoc_data":
01062             lib.add_file("_pydoc.css")
01063         if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email":
01064             # This should contain all non-.svn files listed in subversion
01065             for f in os.listdir(lib.absolute):
01066                 if f.endswith(".txt") or f==".svn":continue
01067                 if f.endswith(".au") or f.endswith(".gif"):
01068                     lib.add_file(f)
01069                 else:
01070                     print("WARNING: New file %s in email/test/data" % f)
01071         for f in os.listdir(lib.absolute):
01072             if os.path.isdir(os.path.join(lib.absolute, f)):
01073                 pydirs.append((lib, f))
01074     for d in dirs:
01075         d.check_unpackaged()
01076     # Add DLLs
01077     default_feature.set_current()
01078     lib = DLLs
01079     lib.add_file("py.ico", src=srcdir+"/PC/py.ico")
01080     lib.add_file("pyc.ico", src=srcdir+"/PC/pyc.ico")
01081     dlls = []
01082     tclfiles = []
01083     for f in extensions:
01084         if f=="_tkinter.pyd":
01085             continue
01086         if not os.path.exists(srcdir + "/" + PCBUILD + "/" + f):
01087             print("WARNING: Missing extension", f)
01088             continue
01089         dlls.append(f)
01090         lib.add_file(f)
01091     lib.add_file('python3.dll')
01092     # Add sqlite
01093     if msilib.msi_type=="Intel64;1033":
01094         sqlite_arch = "/ia64"
01095     elif msilib.msi_type=="x64;1033":
01096         sqlite_arch = "/amd64"
01097         tclsuffix = "64"
01098     else:
01099         sqlite_arch = ""
01100         tclsuffix = ""
01101     lib.add_file("sqlite3.dll")
01102     if have_tcl:
01103         if not os.path.exists("%s/%s/_tkinter.pyd" % (srcdir, PCBUILD)):
01104             print("WARNING: Missing _tkinter.pyd")
01105         else:
01106             lib.start_component("TkDLLs", tcltk)
01107             lib.add_file("_tkinter.pyd")
01108             dlls.append("_tkinter.pyd")
01109             tcldir = os.path.normpath(srcdir+("/../tcltk%s/bin" % tclsuffix))
01110             for f in glob.glob1(tcldir, "*.dll"):
01111                 lib.add_file(f, src=os.path.join(tcldir, f))
01112     # check whether there are any unknown extensions
01113     for f in glob.glob1(srcdir+"/"+PCBUILD, "*.pyd"):
01114         if f.endswith("_d.pyd"): continue # debug version
01115         if f in dlls: continue
01116         print("WARNING: Unknown extension", f)
01117 
01118     # Add headers
01119     default_feature.set_current()
01120     lib = PyDirectory(db, cab, root, "include", "include", "INCLUDE|include")
01121     lib.glob("*.h")
01122     lib.add_file("pyconfig.h", src="../PC/pyconfig.h")
01123     # Add import libraries
01124     lib = PyDirectory(db, cab, root, PCBUILD, "libs", "LIBS|libs")
01125     for f in dlls:
01126         lib.add_file(f.replace('pyd','lib'))
01127     lib.add_file('python%s%s.lib' % (major, minor))
01128     lib.add_file('python3.lib')
01129     # Add the mingw-format library
01130     if have_mingw:
01131         lib.add_file('libpython%s%s.a' % (major, minor))
01132     if have_tcl:
01133         # Add Tcl/Tk
01134         tcldirs = [(root, '../tcltk%s/lib' % tclsuffix, 'tcl')]
01135         tcltk.set_current()
01136         while tcldirs:
01137             parent, phys, dir = tcldirs.pop()
01138             lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir))
01139             if not os.path.exists(lib.absolute):
01140                 continue
01141             for f in os.listdir(lib.absolute):
01142                 if os.path.isdir(os.path.join(lib.absolute, f)):
01143                     tcldirs.append((lib, f, f))
01144                 else:
01145                     lib.add_file(f)
01146     # Add tools
01147     tools.set_current()
01148     tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools")
01149     for f in ['i18n', 'pynche', 'Scripts']:
01150         lib = PyDirectory(db, cab, tooldir, f, f, "%s|%s" % (tooldir.make_short(f), f))
01151         lib.glob("*.py")
01152         lib.glob("*.pyw", exclude=['pydocgui.pyw'])
01153         lib.remove_pyc()
01154         lib.glob("*.txt")
01155         if f == "pynche":
01156             x = PyDirectory(db, cab, lib, "X", "X", "X|X")
01157             x.glob("*.txt")
01158         if os.path.exists(os.path.join(lib.absolute, "README")):
01159             lib.add_file("README.txt", src="README")
01160         if f == 'Scripts':
01161             lib.add_file("2to3.py", src="2to3")
01162             if have_tcl:
01163                 lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw")
01164                 lib.add_file("pydocgui.pyw")
01165     # Add documentation
01166     htmlfiles.set_current()
01167     lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc")
01168     lib.start_component("documentation", keyfile=docfile)
01169     lib.add_file(docfile, src="build/htmlhelp/"+docfile)
01170 
01171     cab.commit(db)
01172 
01173     for f in tmpfiles:
01174         os.unlink(f)
01175 
# See "Registry Table", "Component Table"

Here is the call graph for this function:

Here is the caller graph for this function:

def msi.add_registry (   db)

Definition at line 1176 of file msi.py.

01176 
01177 def add_registry(db):
01178     # File extensions, associated with the REGISTRY.def component
01179     # IDLE verbs depend on the tcltk feature.
01180     # msidbComponentAttributesRegistryKeyPath = 4
01181     # -1 for Root specifies "dependent on ALLUSERS property"
01182     tcldata = []
01183     if have_tcl:
01184         tcldata = [
01185             ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
01186              "py.IDLE")]
01187     add_data(db, "Component",
01188              # msidbComponentAttributesRegistryKeyPath = 4
01189              [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
01190                "InstallPath"),
01191               ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", registry_component, None,
01192                "Documentation"),
01193               ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", registry_component,
01194                None, None)] + tcldata)
01195     # See "FeatureComponents Table".
01196     # The association between TclTk and pythonw.exe is necessary to make ICE59
01197     # happy, because the installer otherwise believes that the IDLE and PyDoc
01198     # shortcuts might get installed without pythonw.exe being install. This
01199     # is not true, since installing TclTk will install the default feature, which
01200     # will cause pythonw.exe to be installed.
01201     # REGISTRY.tcl is not associated with any feature, as it will be requested
01202     # through a custom action
01203     tcldata = []
01204     if have_tcl:
01205         tcldata = [(tcltk.id, "pythonw.exe")]
01206     add_data(db, "FeatureComponents",
01207              [(default_feature.id, "REGISTRY"),
01208               (htmlfiles.id, "REGISTRY.doc"),
01209               (ext_feature.id, "REGISTRY.def")] +
01210               tcldata
01211               )
01212     # Extensions are not advertised. For advertised extensions,
01213     # we would need separate binaries that install along with the
01214     # extension.
01215     pat = r"Software\Classes\%sPython.%sFile\shell\%s\command"
01216     ewi = "Edit with IDLE"
01217     pat2 = r"Software\Classes\%sPython.%sFile\DefaultIcon"
01218     pat3 = r"Software\Classes\%sPython.%sFile"
01219     pat4 = r"Software\Classes\%sPython.%sFile\shellex\DropHandler"
01220     tcl_verbs = []
01221     if have_tcl:
01222         tcl_verbs=[
01223              ("py.IDLE", -1, pat % (testprefix, "", ewi), "",
01224               r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"',
01225               "REGISTRY.tcl"),
01226              ("pyw.IDLE", -1, pat % (testprefix, "NoCon", ewi), "",
01227               r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"',
01228               "REGISTRY.tcl"),
01229         ]
01230     add_data(db, "Registry",
01231             [# Extensions
01232              ("py.ext", -1, r"Software\Classes\."+ext, "",
01233               "Python.File", "REGISTRY.def"),
01234              ("pyw.ext", -1, r"Software\Classes\."+ext+'w', "",
01235               "Python.NoConFile", "REGISTRY.def"),
01236              ("pyc.ext", -1, r"Software\Classes\."+ext+'c', "",
01237               "Python.CompiledFile", "REGISTRY.def"),
01238              ("pyo.ext", -1, r"Software\Classes\."+ext+'o', "",
01239               "Python.CompiledFile", "REGISTRY.def"),
01240              # MIME types
01241              ("py.mime", -1, r"Software\Classes\."+ext, "Content Type",
01242               "text/plain", "REGISTRY.def"),
01243              ("pyw.mime", -1, r"Software\Classes\."+ext+'w', "Content Type",
01244               "text/plain", "REGISTRY.def"),
01245              #Verbs
01246              ("py.open", -1, pat % (testprefix, "", "open"), "",
01247               r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"),
01248              ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "",
01249               r'"[TARGETDIR]pythonw.exe" "%1" %*', "REGISTRY.def"),
01250              ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "",
01251               r'"[TARGETDIR]python.exe" "%1" %*', "REGISTRY.def"),
01252              ] + tcl_verbs + [
01253              #Icons
01254              ("py.icon", -1, pat2 % (testprefix, ""), "",
01255               r'[DLLs]py.ico', "REGISTRY.def"),
01256              ("pyw.icon", -1, pat2 % (testprefix, "NoCon"), "",
01257               r'[DLLs]py.ico', "REGISTRY.def"),
01258              ("pyc.icon", -1, pat2 % (testprefix, "Compiled"), "",
01259               r'[DLLs]pyc.ico', "REGISTRY.def"),
01260              # Descriptions
01261              ("py.txt", -1, pat3 % (testprefix, ""), "",
01262               "Python File", "REGISTRY.def"),
01263              ("pyw.txt", -1, pat3 % (testprefix, "NoCon"), "",
01264               "Python File (no console)", "REGISTRY.def"),
01265              ("pyc.txt", -1, pat3 % (testprefix, "Compiled"), "",
01266               "Compiled Python File", "REGISTRY.def"),
01267              # Drop Handler
01268              ("py.drop", -1, pat4 % (testprefix, ""), "",
01269               "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
01270              ("pyw.drop", -1, pat4 % (testprefix, "NoCon"), "",
01271               "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
01272              ("pyc.drop", -1, pat4 % (testprefix, "Compiled"), "",
01273               "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"),
01274             ])
01275 
01276     # Registry keys
01277     prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version)
01278     add_data(db, "Registry",
01279              [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"),
01280               ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "",
01281                "Python %s" % short_version, "REGISTRY"),
01282               ("PythonPath", -1, prefix+r"\PythonPath", "",
01283                r"[TARGETDIR]Lib;[TARGETDIR]DLLs", "REGISTRY"),
01284               ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "",
01285                "[TARGETDIR]Doc\\"+docfile , "REGISTRY.doc"),
01286               ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"),
01287               ("AppPaths", -1, r"Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe",
01288                "", r"[TARGETDIR]Python.exe", "REGISTRY.def"),
01289               ("DisplayIcon", -1,
01290                r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % product_code,
01291                "DisplayIcon", "[TARGETDIR]python.exe", "REGISTRY")
01292               ])
01293     # Shortcuts, see "Shortcut Table"
01294     add_data(db, "Directory",
01295              [("ProgramMenuFolder", "TARGETDIR", "."),
01296               ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))])
01297     add_data(db, "RemoveFile",
01298              [("MenuDir", "TARGETDIR", None, "MenuDir", 2)])
01299     tcltkshortcuts = []
01300     if have_tcl:
01301         tcltkshortcuts = [
01302               ("IDLE", "MenuDir", "IDLE|IDLE (Python GUI)", "pythonw.exe",
01303                tcltk.id, r'"[TARGETDIR]Lib\idlelib\idle.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"),
01304               ("PyDoc", "MenuDir", "MODDOCS|Module Docs", "pythonw.exe",
01305                tcltk.id, r'"[TARGETDIR]Tools\scripts\pydocgui.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"),
01306               ]
01307     add_data(db, "Shortcut",
01308              tcltkshortcuts +
01309              [# Advertised shortcuts: targets are features, not files
01310               ("Python", "MenuDir", "PYTHON|Python (command line)", "python.exe",
01311                default_feature.id, None, None, None, "python_icon.exe", 2, None, "TARGETDIR"),
01312               # Advertising the Manual breaks on (some?) Win98, and the shortcut lacks an
01313               # icon first.
01314               #("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation",
01315               # htmlfiles.id, None, None, None, None, None, None, None),
01316               ## Non-advertised shortcuts: must be associated with a registry component
01317               ("Manual", "MenuDir", "MANUAL|Python Manuals", "REGISTRY.doc",
01318                "[#%s]" % docfile, None,
01319                None, None, None, None, None, None),
01320               ("Uninstall", "MenuDir", "UNINST|Uninstall Python", "REGISTRY",
01321                SystemFolderName+"msiexec",  "/x%s" % product_code,
01322                None, None, None, None, None, None),
01323               ])
01324     db.Commit()

Here is the call graph for this function:

Here is the caller graph for this function:

def msi.add_ui (   db)

Definition at line 350 of file msi.py.

00350 
00351 def add_ui(db):
00352     x = y = 50
00353     w = 370
00354     h = 300
00355     title = "[ProductName] Setup"
00356 
00357     # see "Dialog Style Bits"
00358     modal = 3      # visible | modal
00359     modeless = 1   # visible
00360     track_disk_space = 32
00361 
00362     add_data(db, 'ActionText', uisample.ActionText)
00363     add_data(db, 'UIText', uisample.UIText)
00364 
00365     # Bitmaps
00366     if not os.path.exists(srcdir+r"\PC\python_icon.exe"):
00367         raise RuntimeError("Run icons.mak in PC directory")
00368     add_data(db, "Binary",
00369              [("PythonWin", msilib.Binary(r"%s\PCbuild\installer.bmp" % srcdir)), # 152x328 pixels
00370               ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")),
00371              ])
00372     add_data(db, "Icon",
00373              [("python_icon.exe", msilib.Binary(srcdir+r"\PC\python_icon.exe"))])
00374 
00375     # Scripts
00376     # CheckDir sets TargetExists if TARGETDIR exists.
00377     # UpdateEditIDLE sets the REGISTRY.tcl component into
00378     # the installed/uninstalled state according to both the
00379     # Extensions and TclTk features.
00380     if os.system("nmake /nologo /c /f msisupport.mak") != 0:
00381         raise RuntimeError("'nmake /f msisupport.mak' failed")
00382     add_data(db, "Binary", [("Script", msilib.Binary("msisupport.dll"))])
00383     # See "Custom Action Type 1"
00384     if msilib.Win64:
00385         CheckDir = "CheckDir"
00386         UpdateEditIDLE = "UpdateEditIDLE"
00387     else:
00388         CheckDir =  "_CheckDir@4"
00389         UpdateEditIDLE = "_UpdateEditIDLE@4"
00390     add_data(db, "CustomAction",
00391         [("CheckDir", 1, "Script", CheckDir)])
00392     if have_tcl:
00393         add_data(db, "CustomAction",
00394         [("UpdateEditIDLE", 1, "Script", UpdateEditIDLE)])
00395 
00396     # UI customization properties
00397     add_data(db, "Property",
00398              # See "DefaultUIFont Property"
00399              [("DefaultUIFont", "DlgFont8"),
00400               # See "ErrorDialog Style Bit"
00401               ("ErrorDialog", "ErrorDlg"),
00402               ("Progress1", "Install"),   # modified in maintenance type dlg
00403               ("Progress2", "installs"),
00404               ("MaintenanceForm_Action", "Repair")])
00405 
00406     # Fonts, see "TextStyle Table"
00407     add_data(db, "TextStyle",
00408              [("DlgFont8", "Tahoma", 9, None, 0),
00409               ("DlgFontBold8", "Tahoma", 8, None, 1), #bold
00410               ("VerdanaBold10", "Verdana", 10, None, 1),
00411               ("VerdanaRed9", "Verdana", 9, 255, 0),
00412              ])
00413 
00414     compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|lib2to3\\tests" "[TARGETDIR]Lib"'
00415     lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"'
00416     # See "CustomAction Table"
00417     add_data(db, "CustomAction", [
00418         # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
00419         # See "Custom Action Type 51",
00420         # "Custom Action Execution Scheduling Options"
00421         ("InitialTargetDir", 307, "TARGETDIR",
00422          "[WindowsVolume]Python%s%s" % (major, minor)),
00423         ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"),
00424         ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName),
00425         # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile
00426         # See "Custom Action Type 18"
00427         ("CompilePyc", 18, "python.exe", compileargs),
00428         ("CompilePyo", 18, "python.exe", "-O "+compileargs),
00429         ("CompileGrammar", 18, "python.exe", lib2to3args),
00430         ])
00431 
00432     # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
00433     # Numbers indicate sequence; see sequence.py for how these action integrate
00434     add_data(db, "InstallUISequence",
00435              [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140),
00436               ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141),
00437               ("InitialTargetDir", 'TARGETDIR=""', 750),
00438               # In the user interface, assume all-users installation if privileged.
00439               ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
00440               ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
00441               ("SelectDirectoryDlg", "Not Installed", 1230),
00442               # XXX no support for resume installations yet
00443               #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
00444               ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250),
00445               ("ProgressDlg", None, 1280)])
00446     add_data(db, "AdminUISequence",
00447              [("InitialTargetDir", 'TARGETDIR=""', 750),
00448               ("SetDLLDirToTarget", 'DLLDIR=""', 751),
00449              ])
00450 
00451     # Execute Sequences
00452     add_data(db, "InstallExecuteSequence",
00453             [("InitialTargetDir", 'TARGETDIR=""', 750),
00454              ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751),
00455              ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752),
00456              ("UpdateEditIDLE", None, 1050),
00457              ("CompilePyc", "COMPILEALL", 6800),
00458              ("CompilePyo", "COMPILEALL", 6801),
00459              ("CompileGrammar", "COMPILEALL", 6802),
00460             ])
00461     add_data(db, "AdminExecuteSequence",
00462             [("InitialTargetDir", 'TARGETDIR=""', 750),
00463              ("SetDLLDirToTarget", 'DLLDIR=""', 751),
00464              ("CompilePyc", "COMPILEALL", 6800),
00465              ("CompilePyo", "COMPILEALL", 6801),
00466              ("CompileGrammar", "COMPILEALL", 6802),
00467             ])
00468 
00469     #####################################################################
00470     # Standard dialogs: FatalError, UserExit, ExitDialog
00471     fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title,
00472                  "Finish", "Finish", "Finish")
00473     fatal.title("[ProductName] Installer ended prematurely")
00474     fatal.back("< Back", "Finish", active = 0)
00475     fatal.cancel("Cancel", "Back", active = 0)
00476     fatal.text("Description1", 135, 70, 220, 80, 0x30003,
00477                "[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.")
00478     fatal.text("Description2", 135, 155, 220, 20, 0x30003,
00479                "Click the Finish button to exit the Installer.")
00480     c=fatal.next("Finish", "Cancel", name="Finish")
00481     # See "ControlEvent Table". Parameters are the event, the parameter
00482     # to the action, and optionally the condition for the event, and the order
00483     # of events.
00484     c.event("EndDialog", "Exit")
00485 
00486     user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title,
00487                  "Finish", "Finish", "Finish")
00488     user_exit.title("[ProductName] Installer was interrupted")
00489     user_exit.back("< Back", "Finish", active = 0)
00490     user_exit.cancel("Cancel", "Back", active = 0)
00491     user_exit.text("Description1", 135, 70, 220, 80, 0x30003,
00492                "[ProductName] setup was interrupted.  Your system has not been modified.  "
00493                "To install this program at a later time, please run the installation again.")
00494     user_exit.text("Description2", 135, 155, 220, 20, 0x30003,
00495                "Click the Finish button to exit the Installer.")
00496     c = user_exit.next("Finish", "Cancel", name="Finish")
00497     c.event("EndDialog", "Exit")
00498 
00499     exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title,
00500                          "Finish", "Finish", "Finish")
00501     exit_dialog.title("Completing the [ProductName] Installer")
00502     exit_dialog.back("< Back", "Finish", active = 0)
00503     exit_dialog.cancel("Cancel", "Back", active = 0)
00504     exit_dialog.text("Acknowledgements", 135, 95, 220, 120, 0x30003,
00505       "Special Windows thanks to:\n"
00506       "    Mark Hammond, without whose years of freely \n"
00507       "    shared Windows expertise, Python for Windows \n"
00508       "    would still be Python for DOS.")
00509 
00510     c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003,
00511             "{\\VerdanaRed9}Warning: Python 2.5.x is the last "
00512             "Python release for Windows 9x.")
00513     c.condition("Hide", "NOT Version9X")
00514 
00515     exit_dialog.text("Description", 135, 235, 220, 20, 0x30003,
00516                "Click the Finish button to exit the Installer.")
00517     c = exit_dialog.next("Finish", "Cancel", name="Finish")
00518     c.event("EndDialog", "Return")
00519 
00520     #####################################################################
00521     # Required dialog: FilesInUse, ErrorDlg
00522     inuse = PyDialog(db, "FilesInUse",
00523                      x, y, w, h,
00524                      19,                # KeepModeless|Modal|Visible
00525                      title,
00526                      "Retry", "Retry", "Retry", bitmap=False)
00527     inuse.text("Title", 15, 6, 200, 15, 0x30003,
00528                r"{\DlgFontBold8}Files in Use")
00529     inuse.text("Description", 20, 23, 280, 20, 0x30003,
00530                "Some files that need to be updated are currently in use.")
00531     inuse.text("Text", 20, 55, 330, 50, 3,
00532                "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.")
00533     inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess",
00534                   None, None, None)
00535     c=inuse.back("Exit", "Ignore", name="Exit")
00536     c.event("EndDialog", "Exit")
00537     c=inuse.next("Ignore", "Retry", name="Ignore")
00538     c.event("EndDialog", "Ignore")
00539     c=inuse.cancel("Retry", "Exit", name="Retry")
00540     c.event("EndDialog","Retry")
00541 
00542 
00543     # See "Error Dialog". See "ICE20" for the required names of the controls.
00544     error = Dialog(db, "ErrorDlg",
00545                    50, 10, 330, 101,
00546                    65543,       # Error|Minimize|Modal|Visible
00547                    title,
00548                    "ErrorText", None, None)
00549     error.text("ErrorText", 50,9,280,48,3, "")
00550     error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None)
00551     error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo")
00552     error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes")
00553     error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort")
00554     error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel")
00555     error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore")
00556     error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk")
00557     error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry")
00558 
00559     #####################################################################
00560     # Global "Query Cancel" dialog
00561     cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title,
00562                     "No", "No", "No")
00563     cancel.text("Text", 48, 15, 194, 30, 3,
00564                 "Are you sure you want to cancel [ProductName] installation?")
00565     cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
00566                    "py.ico", None, None)
00567     c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
00568     c.event("EndDialog", "Exit")
00569 
00570     c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
00571     c.event("EndDialog", "Return")
00572 
00573     #####################################################################
00574     # Global "Wait for costing" dialog
00575     costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title,
00576                      "Return", "Return", "Return")
00577     costing.text("Text", 48, 15, 194, 30, 3,
00578                  "Please wait while the installer finishes determining your disk space requirements.")
00579     costing.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None,
00580                     "py.ico", None, None)
00581     c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None)
00582     c.event("EndDialog", "Exit")
00583 
00584     #####################################################################
00585     # Preparation dialog: no user input except cancellation
00586     prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title,
00587                     "Cancel", "Cancel", "Cancel")
00588     prep.text("Description", 135, 70, 220, 40, 0x30003,
00589               "Please wait while the Installer prepares to guide you through the installation.")
00590     prep.title("Welcome to the [ProductName] Installer")
00591     c=prep.text("ActionText", 135, 110, 220, 20, 0x30003, "Pondering...")
00592     c.mapping("ActionText", "Text")
00593     c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None)
00594     c.mapping("ActionData", "Text")
00595     prep.back("Back", None, active=0)
00596     prep.next("Next", None, active=0)
00597     c=prep.cancel("Cancel", None)
00598     c.event("SpawnDialog", "CancelDlg")
00599 
00600     #####################################################################
00601     # Target directory selection
00602     seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title,
00603                     "Next", "Next", "Cancel")
00604     seldlg.title("Select Destination Directory")
00605     c = seldlg.text("Existing", 135, 25, 235, 30, 0x30003,
00606                     "{\VerdanaRed9}This update will replace your existing [ProductLine] installation.")
00607     c.condition("Hide", 'REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""')
00608     seldlg.text("Description", 135, 50, 220, 40, 0x30003,
00609                "Please select a directory for the [ProductName] files.")
00610 
00611     seldlg.back("< Back", None, active=0)
00612     c = seldlg.next("Next >", "Cancel")
00613     c.event("DoAction", "CheckDir", "TargetExistsOk<>1", order=1)
00614     # If the target exists, but we found that we are going to remove old versions, don't bother
00615     # confirming that the target directory exists. Strictly speaking, we should determine that
00616     # the target directory is indeed the target of the product that we are going to remove, but
00617     # I don't know how to do that.
00618     c.event("SpawnDialog", "ExistingDirectoryDlg", 'TargetExists=1 and REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""', 2)
00619     c.event("SetTargetPath", "TARGETDIR", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 3)
00620     c.event("SpawnWaitDialog", "WaitForCostingDlg", "CostingComplete=1", 4)
00621     c.event("NewDialog", "SelectFeaturesDlg", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 5)
00622 
00623     c = seldlg.cancel("Cancel", "DirectoryCombo")
00624     c.event("SpawnDialog", "CancelDlg")
00625 
00626     seldlg.control("DirectoryCombo", "DirectoryCombo", 135, 70, 172, 80, 393219,
00627                    "TARGETDIR", None, "DirectoryList", None)
00628     seldlg.control("DirectoryList", "DirectoryList", 135, 90, 208, 136, 3, "TARGETDIR",
00629                    None, "PathEdit", None)
00630     seldlg.control("PathEdit", "PathEdit", 135, 230, 206, 16, 3, "TARGETDIR", None, "Next", None)
00631     c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None)
00632     c.event("DirectoryListUp", "0")
00633     c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None)
00634     c.event("DirectoryListNew", "0")
00635 
00636     #####################################################################
00637     # SelectFeaturesDlg
00638     features = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal|track_disk_space,
00639                         title, "Tree", "Next", "Cancel")
00640     features.title("Customize [ProductName]")
00641     features.text("Description", 135, 35, 220, 15, 0x30003,
00642                   "Select the way you want features to be installed.")
00643     features.text("Text", 135,45,220,30, 3,
00644                   "Click on the icons in the tree below to change the way features will be installed.")
00645 
00646     c=features.back("< Back", "Next")
00647     c.event("NewDialog", "SelectDirectoryDlg")
00648 
00649     c=features.next("Next >", "Cancel")
00650     c.mapping("SelectionNoItems", "Enabled")
00651     c.event("SpawnDialog", "DiskCostDlg", "OutOfDiskSpace=1", order=1)
00652     c.event("EndDialog", "Return", "OutOfDiskSpace<>1", order=2)
00653 
00654     c=features.cancel("Cancel", "Tree")
00655     c.event("SpawnDialog", "CancelDlg")
00656 
00657     # The browse property is not used, since we have only a single target path (selected already)
00658     features.control("Tree", "SelectionTree", 135, 75, 220, 95, 7, "_BrowseProperty",
00659                      "Tree of selections", "Back", None)
00660 
00661     #c=features.pushbutton("Reset", 42, 243, 56, 17, 3, "Reset", "DiskCost")
00662     #c.mapping("SelectionNoItems", "Enabled")
00663     #c.event("Reset", "0")
00664 
00665     features.control("Box", "GroupBox", 135, 170, 225, 90, 1, None, None, None, None)
00666 
00667     c=features.xbutton("DiskCost", "Disk &Usage", None, 0.10)
00668     c.mapping("SelectionNoItems","Enabled")
00669     c.event("SpawnDialog", "DiskCostDlg")
00670 
00671     c=features.xbutton("Advanced", "Advanced", None, 0.30)
00672     c.event("SpawnDialog", "AdvancedDlg")
00673 
00674     c=features.text("ItemDescription", 140, 180, 210, 30, 3,
00675                   "Multiline description of the currently selected item.")
00676     c.mapping("SelectionDescription","Text")
00677 
00678     c=features.text("ItemSize", 140, 210, 210, 45, 3,
00679                     "The size of the currently selected item.")
00680     c.mapping("SelectionSize", "Text")
00681 
00682     #####################################################################
00683     # Disk cost
00684     cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title,
00685                     "OK", "OK", "OK", bitmap=False)
00686     cost.text("Title", 15, 6, 200, 15, 0x30003,
00687               "{\DlgFontBold8}Disk Space Requirements")
00688     cost.text("Description", 20, 20, 280, 20, 0x30003,
00689               "The disk space required for the installation of the selected features.")
00690     cost.text("Text", 20, 53, 330, 60, 3,
00691               "The highlighted volumes (if any) do not have enough disk space "
00692               "available for the currently selected features.  You can either "
00693               "remove some files from the highlighted volumes, or choose to "
00694               "install less features onto local drive(s), or select different "
00695               "destination drive(s).")
00696     cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223,
00697                  None, "{120}{70}{70}{70}{70}", None, None)
00698     cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return")
00699 
00700     #####################################################################
00701     # WhichUsers Dialog. Only available on NT, and for privileged users.
00702     # This must be run before FindRelatedProducts, because that will
00703     # take into account whether the previous installation was per-user
00704     # or per-machine. We currently don't support going back to this
00705     # dialog after "Next" was selected; to support this, we would need to
00706     # find how to reset the ALLUSERS property, and how to re-run
00707     # FindRelatedProducts.
00708     # On Windows9x, the ALLUSERS property is ignored on the command line
00709     # and in the Property table, but installer fails according to the documentation
00710     # if a dialog attempts to set ALLUSERS.
00711     whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title,
00712                         "AdminInstall", "Next", "Cancel")
00713     whichusers.title("Select whether to install [ProductName] for all users of this computer.")
00714     # A radio group with two options: allusers, justme
00715     g = whichusers.radiogroup("AdminInstall", 135, 60, 235, 80, 3,
00716                               "WhichUsers", "", "Next")
00717     g.condition("Disable", "VersionNT=600") # Not available on Vista and Windows 2008
00718     g.add("ALL", 0, 5, 150, 20, "Install for all users")
00719     g.add("JUSTME", 0, 25, 235, 20, "Install just for me (not available on Windows Vista)")
00720 
00721     whichusers.back("Back", None, active=0)
00722 
00723     c = whichusers.next("Next >", "Cancel")
00724     c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1)
00725     c.event("EndDialog", "Return", order = 2)
00726 
00727     c = whichusers.cancel("Cancel", "AdminInstall")
00728     c.event("SpawnDialog", "CancelDlg")
00729 
00730     #####################################################################
00731     # Advanced Dialog.
00732     advanced = PyDialog(db, "AdvancedDlg", x, y, w, h, modal, title,
00733                         "CompilePyc", "Ok", "Ok")
00734     advanced.title("Advanced Options for [ProductName]")
00735     # A radio group with two options: allusers, justme
00736     advanced.checkbox("CompilePyc", 135, 60, 230, 50, 3,
00737                       "COMPILEALL", "Compile .py files to byte code after installation", "Ok")
00738 
00739     c = advanced.cancel("Ok", "CompilePyc", name="Ok") # Button just has location of cancel button.
00740     c.event("EndDialog", "Return")
00741 
00742     #####################################################################
00743     # Existing Directory dialog
00744     dlg = Dialog(db, "ExistingDirectoryDlg", 50, 30, 200, 80, modal, title,
00745                    "No", "No", "No")
00746     dlg.text("Title", 10, 20, 180, 40, 3,
00747              "[TARGETDIR] exists. Are you sure you want to overwrite existing files?")
00748     c=dlg.pushbutton("Yes", 30, 60, 55, 17, 3, "Yes", "No")
00749     c.event("[TargetExists]", "0", order=1)
00750     c.event("[TargetExistsOk]", "1", order=2)
00751     c.event("EndDialog", "Return", order=3)
00752     c=dlg.pushbutton("No", 115, 60, 55, 17, 3, "No", "Yes")
00753     c.event("EndDialog", "Return")
00754 
00755     #####################################################################
00756     # Installation Progress dialog (modeless)
00757     progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title,
00758                         "Cancel", "Cancel", "Cancel", bitmap=False)
00759     progress.text("Title", 20, 15, 200, 15, 0x30003,
00760                   "{\DlgFontBold8}[Progress1] [ProductName]")
00761     progress.text("Text", 35, 65, 300, 30, 3,
00762                   "Please wait while the Installer [Progress2] [ProductName]. "
00763                   "This may take several minutes.")
00764     progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:")
00765 
00766     c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...")
00767     c.mapping("ActionText", "Text")
00768 
00769     #c=progress.text("ActionData", 35, 140, 300, 20, 3, None)
00770     #c.mapping("ActionData", "Text")
00771 
00772     c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537,
00773                        None, "Progress done", None, None)
00774     c.mapping("SetProgress", "Progress")
00775 
00776     progress.back("< Back", "Next", active=False)
00777     progress.next("Next >", "Cancel", active=False)
00778     progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg")
00779 
00780     # Maintenance type: repair/uninstall
00781     maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title,
00782                      "Next", "Next", "Cancel")
00783     maint.title("Welcome to the [ProductName] Setup Wizard")
00784     maint.text("BodyText", 135, 63, 230, 42, 3,
00785                "Select whether you want to repair or remove [ProductName].")
00786     g=maint.radiogroup("RepairRadioGroup", 135, 108, 230, 60, 3,
00787                         "MaintenanceForm_Action", "", "Next")
00788     g.add("Change", 0, 0, 200, 17, "&Change [ProductName]")
00789     g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]")
00790     g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]")
00791 
00792     maint.back("< Back", None, active=False)
00793     c=maint.next("Finish", "Cancel")
00794     # Change installation: Change progress dialog to "Change", then ask
00795     # for feature selection
00796     c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1)
00797     c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2)
00798 
00799     # Reinstall: Change progress dialog to "Repair", then invoke reinstall
00800     # Also set list of reinstalled features to "ALL"
00801     c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5)
00802     c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6)
00803     c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7)
00804     c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8)
00805 
00806     # Uninstall: Change progress to "Remove", then invoke uninstall
00807     # Also set list of removed features to "ALL"
00808     c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11)
00809     c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12)
00810     c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13)
00811     c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14)
00812 
00813     # Close dialog when maintenance action scheduled
00814     c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20)
00815     c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21)
00816 
00817     maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg")
00818 
00819 
00820 # See "Feature Table". The feature level is 1 for all features,
00821 # and the feature attributes are 0 for the DefaultFeature, and
00822 # FollowParent for all other features. The numbers are the Display
# column.

Here is the call graph for this function:

Here is the caller graph for this function:

Generate an empty database, with just the schema and the
Summary information stream.

Definition at line 214 of file msi.py.

00214 
00215 def build_database():
00216     """Generate an empty database, with just the schema and the
00217     Summary information stream."""
00218     if snapshot:
00219         uc = upgrade_code_snapshot
00220     else:
00221         uc = upgrade_code
00222     if msilib.Win64:
00223         productsuffix = " (64-bit)"
00224     else:
00225         productsuffix = ""
00226     # schema represents the installer 2.0 database schema.
00227     # sequence is the set of standard sequences
00228     # (ui/execute, admin/advt/install)
00229     msiname = "python-%s%s.msi" % (full_current_version, msilib.arch_ext)
00230     db = msilib.init_database(msiname,
00231                   schema, ProductName="Python "+full_current_version+productsuffix,
00232                   ProductCode=product_code,
00233                   ProductVersion=current_version,
00234                   Manufacturer=u"Python Software Foundation",
00235                   request_uac = True)
00236     # The default sequencing of the RemoveExistingProducts action causes
00237     # removal of files that got just installed. Place it after
00238     # InstallInitialize, so we first uninstall everything, but still roll
00239     # back in case the installation is interrupted
00240     msilib.change_sequence(sequence.InstallExecuteSequence,
00241                            "RemoveExistingProducts", 1510)
00242     msilib.add_tables(db, sequence)
00243     # We cannot set ALLUSERS in the property table, as this cannot be
00244     # reset if the user choses a per-user installation. Instead, we
00245     # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages
00246     # this property, and when the execution starts, ALLUSERS is set
00247     # accordingly.
00248     add_data(db, "Property", [("UpgradeCode", uc),
00249                               ("WhichUsers", "ALL"),
00250                               ("ProductLine", "Python%s%s" % (major, minor)),
00251                              ])
00252     db.Commit()
00253     return db, msiname

Here is the call graph for this function:

Here is the caller graph for this function:

def msi.build_mingw_lib (   lib_file,
  def_file,
  dll_file,
  mingw_lib 
)

Definition at line 137 of file msi.py.

00137 
00138 def build_mingw_lib(lib_file, def_file, dll_file, mingw_lib):
00139     warning = "WARNING: %s - libpythonXX.a not built"
00140     nm = find_executable('nm')
00141     dlltool = find_executable('dlltool')
00142 
00143     if not nm or not dlltool:
00144         print(warning % "nm and/or dlltool were not found")
00145         return False
00146 
00147     nm_command = '%s -Cs %s' % (nm, lib_file)
00148     dlltool_command = "%s --dllname %s --def %s --output-lib %s" % \
00149         (dlltool, dll_file, def_file, mingw_lib)
00150     export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match
00151 
00152     f = open(def_file,'w')
00153     f.write("LIBRARY %s\n" % dll_file)
00154     f.write("EXPORTS\n")
00155 
00156     nm_pipe = os.popen(nm_command)
00157     for line in nm_pipe.readlines():
00158         m = export_match(line)
00159         if m:
00160             f.write(m.group(1)+"\n")
00161     f.close()
00162     exit = nm_pipe.close()
00163 
00164     if exit:
00165         print(warning % "nm did not run successfully")
00166         return False
00167 
00168     if os.system(dlltool_command) != 0:
00169         print(warning % "dlltool did not run successfully")
00170         return False
00171 
00172     return True
00173 
# Target files (.def and .a) go in PCBuild directory

Here is the call graph for this function:

Definition at line 1325 of file msi.py.

01325 
01326 def build_pdbzip():
01327     pdbexclude = ['kill_python.pdb', 'make_buildinfo.pdb',
01328                   'make_versioninfo.pdb']
01329     path = "python-%s%s-pdb.zip" % (full_current_version, msilib.arch_ext)
01330     pdbzip = zipfile.ZipFile(path, 'w')
01331     for f in glob.glob1(os.path.join(srcdir, PCBUILD), "*.pdb"):
01332         if f not in pdbexclude and not f.endswith('_d.pdb'):
01333             pdbzip.write(os.path.join(srcdir, PCBUILD, f), f)
01334     pdbzip.close()
01335 
01336 db,msiname = build_database()
01337 try:
01338     add_features(db)
01339     add_ui(db)
01340     add_files(db)
01341     add_registry(db)
01342     remove_old_versions(db)
01343     db.Commit()
01344 finally:
01345     del db
01346 
# Merge CRT into MSI file. This requires the database to be closed.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 857 of file msi.py.

00857 
00858 def extract_msvcr90():
00859     # Find the redistributable files
00860     if msilib.Win64:
00861         arch = "amd64"
00862     else:
00863         arch = "x86"
00864     dir = os.path.join(os.environ['VS90COMNTOOLS'], r"..\..\VC\redist\%s\Microsoft.VC90.CRT" % arch)
00865 
00866     result = []
00867     installer = msilib.MakeInstaller()
00868     # omit msvcm90 and msvcp90, as they aren't really needed
00869     files = ["Microsoft.VC90.CRT.manifest", "msvcr90.dll"]
00870     for f in files:
00871         path = os.path.join(dir, f)
00872         kw = {'src':path}
00873         if f.endswith('.dll'):
00874             kw['version'] = installer.FileVersion(path, 0)
00875             kw['language'] = installer.FileVersion(path, 1)
00876         result.append((f, kw))
00877     return result

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 878 of file msi.py.

00878 
00879 def generate_license():
00880     import shutil, glob
00881     out = open("LICENSE.txt", "w")
00882     shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out)
00883     shutil.copyfileobj(open("crtlicense.txt"), out)
00884     for name, pat, file in (("bzip2","bzip2-*", "LICENSE"),
00885                       ("openssl", "openssl-*", "LICENSE"),
00886                       ("Tcl", "tcl8*", "license.terms"),
00887                       ("Tk", "tk8*", "license.terms"),
00888                       ("Tix", "tix-*", "license.terms")):
00889         out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % name)
00890         dirs = glob.glob(srcdir+"/../"+pat)
00891         if not dirs:
00892             raise ValueError, "Could not find "+srcdir+"/../"+pat
00893         if len(dirs) > 2:
00894             raise ValueError, "Multiple copies of "+pat
00895         dir = dirs[0]
00896         shutil.copyfileobj(open(os.path.join(dir, file)), out)
00897     out.close()
00898 

Here is the call graph for this function:

Here is the caller graph for this function:

def msi.merge (   msi,
  feature,
  rootdir,
  modules 
)

Definition at line 1356 of file msi.py.

01356 
01357 def merge(msi, feature, rootdir, modules):
01358     cab_and_filecount = []
01359     # Step 1: Merge databases, extract cabfiles
01360     m = msilib.MakeMerge2()
01361     m.OpenLog("merge.log")
01362     m.OpenDatabase(msi)
01363     for module in modules:
01364         print module
01365         m.OpenModule(module,0)
01366         m.Merge(feature, rootdir)
01367         print "Errors:"
01368         for e in m.Errors:
01369             print e.Type, e.ModuleTable, e.DatabaseTable
01370             print "   Modkeys:",
01371             for s in e.ModuleKeys: print s,
01372             print
01373             print "   DBKeys:",
01374             for s in e.DatabaseKeys: print s,
01375             print
01376         cabname = tempfile.mktemp(suffix=".cab")
01377         m.ExtractCAB(cabname)
01378         cab_and_filecount.append((cabname, len(m.ModuleFiles)))
01379         m.CloseModule()
01380     m.CloseDatabase(True)
01381     m.CloseLog()
01382 
01383     # Step 2: Add CAB files
01384     i = msilib.MakeInstaller()
01385     db = i.OpenDatabase(msi, constants.msiOpenDatabaseModeTransact)
01386 
01387     v = db.OpenView("SELECT LastSequence FROM Media")
01388     v.Execute(None)
01389     maxmedia = -1
01390     while 1:
01391         r = v.Fetch()
01392         if not r: break
01393         seq = r.IntegerData(1)
01394         if seq > maxmedia:
01395             maxmedia = seq
01396     print "Start of Media", maxmedia
01397 
01398     for cabname, count in cab_and_filecount:
01399         stream = "merged%d" % maxmedia
01400         msilib.add_data(db, "Media",
01401                 [(maxmedia+1, maxmedia+count, None, "#"+stream, None, None)])
01402         msilib.add_stream(db, stream,  cabname)
01403         os.unlink(cabname)
01404         maxmedia += count
01405     # The merge module sets ALLUSERS to 1 in the property table.
01406     # This is undesired; delete that
01407     v = db.OpenView("DELETE FROM Property WHERE Property='ALLUSERS'")
01408     v.Execute(None)
01409     v.Close()
01410     db.Commit()
01411 
01412 merge(msiname, "SharedCRT", "TARGETDIR", modules)
01413 
01414 # certname (from config.py) should be (a substring of)
# the certificate subject, e.g. "Python Software Foundation"

Here is the call graph for this function:

Definition at line 254 of file msi.py.

00254 
00255 def remove_old_versions(db):
00256     "Fill the upgrade table."
00257     start = "%s.%s.0" % (major, minor)
00258     # This requests that feature selection states of an older
00259     # installation should be forwarded into this one. Upgrading
00260     # requires that both the old and the new installation are
00261     # either both per-machine or per-user.
00262     migrate_features = 1
00263     # See "Upgrade Table". We remove releases with the same major and
00264     # minor version. For an snapshot, we remove all earlier snapshots. For
00265     # a release, we remove all snapshots, and all earlier releases.
00266     if snapshot:
00267         add_data(db, "Upgrade",
00268             [(upgrade_code_snapshot, start,
00269               current_version,
00270               None,                     # Ignore language
00271               migrate_features,
00272               None,                     # Migrate ALL features
00273               "REMOVEOLDSNAPSHOT")])
00274         props = "REMOVEOLDSNAPSHOT"
00275     else:
00276         add_data(db, "Upgrade",
00277             [(upgrade_code, start, current_version,
00278               None, migrate_features, None, "REMOVEOLDVERSION"),
00279              (upgrade_code_snapshot, start, "%s.%d.0" % (major, int(minor)+1),
00280               None, migrate_features, None, "REMOVEOLDSNAPSHOT")])
00281         props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION"
00282 
00283     props += ";TARGETDIR;DLLDIR"
00284     # Installer collects the product codes of the earlier releases in
00285     # these properties. In order to allow modification of the properties,
00286     # they must be declared as secure. See "SecureCustomProperties Property"
00287     add_data(db, "Property", [("SecureCustomProperties", props)])

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

msi.certname = None

Definition at line 33 of file msi.py.

Definition at line 67 of file msi.py.

tuple msi.def_file = os.path.join(srcdir, PCBUILD, "python%s%s.def" % (major, minor))

Definition at line 175 of file msi.py.

tuple msi.digit = hex((int(product_code[-2],16)+1)%16)

Definition at line 190 of file msi.py.

string msi.dll_file = "python%s%s.dll"

Definition at line 176 of file msi.py.

Definition at line 182 of file msi.py.

Definition at line 125 of file msi.py.

string msi.ext = 'px'

Definition at line 194 of file msi.py.

Initial value:
00001 [
00002     'bz2.pyd',
00003     'pyexpat.pyd',
00004     'select.pyd',
00005     'unicodedata.pyd',
00006     'winsound.pyd',
00007     '_elementtree.pyd',
00008     '_socket.pyd',
00009     '_ssl.pyd',
00010     '_testcapi.pyd',
00011     '_tkinter.pyd',
00012     '_msi.pyd',
00013     '_ctypes.pyd',
00014     '_ctypes_test.pyd',
00015     '_sqlite3.pyd',
00016     '_hashlib.pyd',
00017     '_multiprocessing.pyd'
00018 ]

Definition at line 87 of file msi.py.

int msi.FIELD3 = 1000

Definition at line 66 of file msi.py.

Definition at line 25 of file msi.py.

Definition at line 179 of file msi.py.

msi.have_tcl = True

Definition at line 27 of file msi.py.

tuple msi.l = l.split()

Definition at line 54 of file msi.py.

Initial value:
00001 {
00002     'PY_RELEASE_LEVEL_ALPHA':0xA,
00003     'PY_RELEASE_LEVEL_BETA': 0xB,
00004     'PY_RELEASE_LEVEL_GAMMA':0xC,
00005     'PY_RELEASE_LEVEL_FINAL':0xF
00006     }

Definition at line 45 of file msi.py.

tuple msi.lib_file = os.path.join(srcdir, PCBUILD, "python%s%s.lib" % (major, minor))

Definition at line 174 of file msi.py.

tuple msi.lines = open(srcdir + "/Include/patchlevel.h")

Definition at line 43 of file msi.py.

msi.major = minormicrolevelserialNone

Definition at line 44 of file msi.py.

tuple msi.mingw_lib = os.path.join(srcdir, PCBUILD, "libpython%s%s.a" % (major, minor))

Definition at line 177 of file msi.py.

tuple msi.mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules")

Definition at line 1347 of file msi.py.

list msi.modules = ["Microsoft_VC90_CRT_x86_x64.msm", "policy_9_0_Microsoft_VC90_CRT_x86_x64.msm"]

Definition at line 1349 of file msi.py.

string msi.MSVCR = "90"

Definition at line 31 of file msi.py.

string msi.PCBUILD = "PCbuild"

Definition at line 29 of file msi.py.

msi.pdbzip = True

Definition at line 35 of file msi.py.

Definition at line 80 of file msi.py.

Initial value:
00001 {
00002     "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}",
00003     "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}",
00004     "26":"{34ebecac-f046-4e1c-b0e3-9bac3cdaacfa}",
00005     "27":"{4fe21c76-1760-437b-a2f2-99909130a175}",
00006     "30":"{6953bc3b-6768-4291-8410-7914ce6e2ca8}",
00007     "31":"{4afcba0b-13e4-47c3-bebe-477428b46913}",
00008     "32":"{3ff95315-1096-4d31-bd86-601d5438ad5e}",
00009     }

Definition at line 114 of file msi.py.

Definition at line 202 of file msi.py.

Definition at line 64 of file msi.py.

Definition at line 16 of file msi.py.

tuple msi.srcdir = os.path.abspath("../..")

Definition at line 21 of file msi.py.

string msi.sys32cond = "(Windows9x or (Privileged and ALLUSERS))"

Definition at line 212 of file msi.py.

string msi.SystemFolderName = "[System64Folder]"

Definition at line 201 of file msi.py.

Definition at line 19 of file msi.py.

Definition at line 195 of file msi.py.

msi.upgrade_code = '{65E6DE48-A358-434D-AA4F-4AF72DB4718F}'

Definition at line 75 of file msi.py.

string msi.upgrade_code_64 = '{6A965A0C-6EE6-4E3A-9983-3263F56311EC}'

Definition at line 76 of file msi.py.

string msi.upgrade_code_snapshot = '{92A24481-3ECB-40FC-8836-04B7966EC0D5}'

Definition at line 74 of file msi.py.