@@ -286,7 +286,7 @@ def remove_old_versions(db):
286286 None , migrate_features , None , "REMOVEOLDSNAPSHOT" )])
287287 props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION"
288288
289- props += ";TARGETDIR;DLLDIR"
289+ props += ";TARGETDIR;DLLDIR;LAUNCHERDIR "
290290 # Installer collects the product codes of the earlier releases in
291291 # these properties. In order to allow modification of the properties,
292292 # they must be declared as secure. See "SecureCustomProperties Property"
@@ -426,6 +426,8 @@ def add_ui(db):
426426 "[WindowsVolume]Python%s%s" % (major , minor )),
427427 ("SetDLLDirToTarget" , 307 , "DLLDIR" , "[TARGETDIR]" ),
428428 ("SetDLLDirToSystem32" , 307 , "DLLDIR" , SystemFolderName ),
429+ ("SetLauncherDirToTarget" , 307 , "LAUNCHERDIR" , "[TARGETDIR]" ),
430+ ("SetLauncherDirToWindows" , 307 , "LAUNCHERDIR" , "[WindowsFolder]" ),
429431 # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile
430432 # See "Custom Action Type 18"
431433 ("CompilePyc" , 18 , "python.exe" , compileargs ),
@@ -442,6 +444,8 @@ def add_ui(db):
442444 # In the user interface, assume all-users installation if privileged.
443445 ("SetDLLDirToSystem32" , 'DLLDIR="" and ' + sys32cond , 751 ),
444446 ("SetDLLDirToTarget" , 'DLLDIR="" and not ' + sys32cond , 752 ),
447+ ("SetLauncherDirToWindows" , 'LAUNCHERDIR="" and ' + sys32cond , 753 ),
448+ ("SetLauncherDirToTarget" , 'LAUNCHERDIR="" and not ' + sys32cond , 754 ),
445449 ("SelectDirectoryDlg" , "Not Installed" , 1230 ),
446450 # XXX no support for resume installations yet
447451 #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240),
@@ -450,6 +454,7 @@ def add_ui(db):
450454 add_data (db , "AdminUISequence" ,
451455 [("InitialTargetDir" , 'TARGETDIR=""' , 750 ),
452456 ("SetDLLDirToTarget" , 'DLLDIR=""' , 751 ),
457+ ("SetLauncherDirToTarget" , 'LAUNCHERDIR=""' , 752 ),
453458 ])
454459
455460 # Prepend TARGETDIR to the system path, and remove it on uninstall.
@@ -461,6 +466,8 @@ def add_ui(db):
461466 [("InitialTargetDir" , 'TARGETDIR=""' , 750 ),
462467 ("SetDLLDirToSystem32" , 'DLLDIR="" and ' + sys32cond , 751 ),
463468 ("SetDLLDirToTarget" , 'DLLDIR="" and not ' + sys32cond , 752 ),
469+ ("SetLauncherDirToWindows" , 'LAUNCHERDIR="" and ' + sys32cond , 753 ),
470+ ("SetLauncherDirToTarget" , 'LAUNCHERDIR="" and not ' + sys32cond , 754 ),
464471 ("UpdateEditIDLE" , None , 1050 ),
465472 ("CompilePyc" , "COMPILEALL" , 6800 ),
466473 ("CompilePyo" , "COMPILEALL" , 6801 ),
@@ -469,6 +476,7 @@ def add_ui(db):
469476 add_data (db , "AdminExecuteSequence" ,
470477 [("InitialTargetDir" , 'TARGETDIR=""' , 750 ),
471478 ("SetDLLDirToTarget" , 'DLLDIR=""' , 751 ),
479+ ("SetLauncherDirToTarget" , 'LAUNCHERDIR=""' , 752 ),
472480 ("CompilePyc" , "COMPILEALL" , 6800 ),
473481 ("CompilePyo" , "COMPILEALL" , 6801 ),
474482 ("CompileGrammar" , "COMPILEALL" , 6802 ),
@@ -904,7 +912,7 @@ def generate_license():
904912 dirs = glob .glob (srcdir + "/../" + pat )
905913 if not dirs :
906914 raise ValueError , "Could not find " + srcdir + "/../" + pat
907- if len (dirs ) > 2 :
915+ if len (dirs ) > 2 and not snapshot :
908916 raise ValueError , "Multiple copies of " + pat
909917 dir = dirs [0 ]
910918 shutil .copyfileobj (open (os .path .join (dir , file )), out )
@@ -939,6 +947,7 @@ def hgmanifest():
939947# See "File Table", "Component Table", "Directory Table",
940948# "FeatureComponents Table"
941949def add_files (db ):
950+ installer = msilib .MakeInstaller ()
942951 hgfiles = hgmanifest ()
943952 cab = CAB ("python" )
944953 tmpfiles = []
@@ -958,11 +967,26 @@ def add_files(db):
958967
959968 # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table"
960969 dlldir = PyDirectory (db , cab , root , srcdir , "DLLDIR" , "." )
970+ launcherdir = PyDirectory (db , cab , root , srcdir , "LAUNCHERDIR" , "." )
971+
972+ # msidbComponentAttributes64bit = 256; this disables registry redirection
973+ # to allow setting the SharedDLLs key in the 64-bit portion even for a
974+ # 32-bit installer.
975+ # XXX does this still allow to install the component on a 32-bit system?
976+ launcher = os .path .join (srcdir , PCBUILD , "py.exe" )
977+ launcherdir .start_component ("launcher" , flags = 8 + 256 , keyfile = "py.exe" )
978+ launcherdir .add_file ("%s/py.exe" % PCBUILD ,
979+ version = installer .FileVersion (launcher , 0 ),
980+ language = installer .FileVersion (launcher , 1 ))
981+ launcherw = os .path .join (srcdir , PCBUILD , "pyw.exe" )
982+ launcherdir .start_component ("launcherw" , flags = 8 + 256 , keyfile = "pyw.exe" )
983+ launcherdir .add_file ("%s/pyw.exe" % PCBUILD ,
984+ version = installer .FileVersion (launcherw , 0 ),
985+ language = installer .FileVersion (launcherw , 1 ))
961986
962987 pydll = "python%s%s.dll" % (major , minor )
963988 pydllsrc = os .path .join (srcdir , PCBUILD , pydll )
964989 dlldir .start_component ("DLLDIR" , flags = 8 , keyfile = pydll , uuid = pythondll_uuid )
965- installer = msilib .MakeInstaller ()
966990 pyversion = installer .FileVersion (pydllsrc , 0 )
967991 if not snapshot :
968992 # For releases, the Python DLL has the same version as the
@@ -1211,11 +1235,11 @@ def add_registry(db):
12111235 "text/plain" , "REGISTRY.def" ),
12121236 #Verbs
12131237 ("py.open" , - 1 , pat % (testprefix , "" , "open" ), "" ,
1214- r'"[TARGETDIR]python .exe" "%1" %*' , "REGISTRY.def" ),
1238+ r'"[LAUNCHERDIR]py .exe" "%1" %*' , "REGISTRY.def" ),
12151239 ("pyw.open" , - 1 , pat % (testprefix , "NoCon" , "open" ), "" ,
1216- r'"[TARGETDIR]pythonw .exe" "%1" %*' , "REGISTRY.def" ),
1240+ r'"[LAUNCHERDIR]pyw .exe" "%1" %*' , "REGISTRY.def" ),
12171241 ("pyc.open" , - 1 , pat % (testprefix , "Compiled" , "open" ), "" ,
1218- r'"[TARGETDIR]python .exe" "%1" %*' , "REGISTRY.def" ),
1242+ r'"[LAUNCHERDIR]py .exe" "%1" %*' , "REGISTRY.def" ),
12191243 ] + tcl_verbs + [
12201244 #Icons
12211245 ("py.icon" , - 1 , pat2 % (testprefix , "" ), "" ,
0 commit comments