summaryrefslogtreecommitdiff
path: root/Tools/msi
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/msi')
-rw-r--r--Tools/msi/buildrelease.bat87
-rw-r--r--Tools/msi/bundle/Default.thm7
-rw-r--r--Tools/msi/bundle/Default.wxl3
-rw-r--r--Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp155
-rw-r--r--Tools/msi/bundle/bundle.icobin19790 -> 0 bytes
-rw-r--r--Tools/msi/bundle/bundle.wxs2
-rw-r--r--Tools/msi/common.wxs12
-rw-r--r--Tools/msi/common_en-US.wxl_template1
-rw-r--r--Tools/msi/exe/exe.wixproj1
-rw-r--r--Tools/msi/exe/exe.wxs2
-rw-r--r--Tools/msi/exe/exe_d.wixproj1
-rw-r--r--Tools/msi/exe/exe_en-US.wxl_template1
-rw-r--r--Tools/msi/exe/exe_files.wxs10
-rw-r--r--Tools/msi/exe/exe_pdb.wixproj1
-rw-r--r--Tools/msi/exe/exe_reg.wxs25
-rw-r--r--Tools/msi/launcher/launcher.wixproj2
-rw-r--r--Tools/msi/launcher/launcher.wxs16
-rw-r--r--Tools/msi/launcher/launcher_en-US.wxl1
-rw-r--r--Tools/msi/launcher/launcher_reg.wxs8
-rw-r--r--Tools/msi/lib/lib.wixproj1
-rw-r--r--Tools/msi/lib/lib.wxs1
-rw-r--r--Tools/msi/lib/lib_files.wxs15
-rw-r--r--Tools/msi/make_zip.proj2
-rw-r--r--Tools/msi/make_zip.py54
-rw-r--r--Tools/msi/msi.props11
-rw-r--r--Tools/msi/msi.targets33
-rw-r--r--Tools/msi/test/test_files.wxs77
-rw-r--r--Tools/msi/tools/tools.wixproj1
-rw-r--r--Tools/msi/tools/tools.wxs1
-rw-r--r--Tools/msi/tools/tools_files.wxs7
30 files changed, 298 insertions, 240 deletions
diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat
index f296e613ac..4659a32b83 100644
--- a/Tools/msi/buildrelease.bat
+++ b/Tools/msi/buildrelease.bat
@@ -35,7 +35,7 @@ set BUILDX86=
set BUILDX64=
set TARGET=Rebuild
set TESTTARGETDIR=
-set PGO=
+set PGO=-m test -q --pgo
set BUILDNUGET=1
set BUILDZIP=1
@@ -57,6 +57,7 @@ if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts
if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts
if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts
if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts
+if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts
if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts
if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts
@@ -109,21 +110,14 @@ exit /B 0
@echo off
if "%1" EQU "x86" (
- call "%PCBUILD%env.bat" x86
+ set PGO=
set BUILD=%PCBUILD%win32\
set BUILD_PLAT=Win32
set OUTDIR_PLAT=win32
set OBJDIR_PLAT=x86
-) else if "%~2" NEQ "" (
- call "%PCBUILD%env.bat" amd64
- set PGO=%~2
- set BUILD=%PCBUILD%amd64-pgo\
- set BUILD_PLAT=x64
- set OUTDIR_PLAT=amd64
- set OBJDIR_PLAT=x64
) else (
- call "%PCBUILD%env.bat" amd64
set BUILD=%PCBUILD%amd64\
+ set PGO=%~2
set BUILD_PLAT=x64
set OUTDIR_PLAT=amd64
set OBJDIR_PLAT=x64
@@ -135,6 +129,12 @@ if exist "%BUILD%en-us" (
if errorlevel 1 exit /B
)
+if exist "%D%obj\Debug_%OBJDIR_PLAT%" (
+ echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%"
+ rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%"
+ if errorlevel 1 exit /B
+)
+
if exist "%D%obj\Release_%OBJDIR_PLAT%" (
echo Deleting "%D%obj\Release_%OBJDIR_PLAT%"
rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%"
@@ -146,45 +146,38 @@ if not "%CERTNAME%" EQU "" (
) else (
set CERTOPTS=
)
-
+if not "%PGO%" EQU "" (
+ set PGOOPTS=--pgo-job "%PGO%"
+) else (
+ set PGOOPTS=
+)
if not "%SKIPBUILD%" EQU "1" (
- @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS%
+ @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
+ @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS%
@if errorlevel 1 exit /B
@rem build.bat turns echo back on, so we disable it again
@echo off
-
- if "%PGO%" EQU "" (
- @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %CERTOPTS%
- ) else (
- @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGInstrument -t %TARGET% %CERTOPTS%
- @if errorlevel 1 exit /B
-
- @del "%BUILD%*.pgc"
- if "%PGO%" EQU "default" (
- "%BUILD%python.exe" -m test -q --pgo
- ) else if "%PGO%" EQU "default2" (
- "%BUILD%python.exe" -m test -r -q --pgo
- "%BUILD%python.exe" -m test -r -q --pgo
- ) else if "%PGO%" EQU "default10" (
- for /L %%i in (0, 1, 9) do "%BUILD%python.exe" -m test -q -r --pgo
- ) else if "%PGO%" EQU "pybench" (
- "%BUILD%python.exe" "%PCBUILD%..\Tools\pybench\pybench.py"
- ) else (
- "%BUILD%python.exe" %PGO%
- )
-
- @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t Build %CERTOPTS%
- )
+
+ @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
+ @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET%
@if errorlevel 1 exit /B
+ @rem build.bat turns echo back on, so we disable it again
@echo off
)
-set BUILDOPTS=/p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI%
-if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD%
-msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
-msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true
+call "%PCBUILD%env.bat"
+if "%OUTDIR_PLAT%" EQU "win32" (
+ msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
+ if errorlevel 1 exit /B
+) else if not exist "%PCBUILD%win32\en-us\launcher.msi" (
+ msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI%
+ if errorlevel 1 exit /B
+)
+
+set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI%
+msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true
if errorlevel 1 exit /B
-msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false
+msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false
if errorlevel 1 exit /B
if defined BUILDZIP (
@@ -210,7 +203,7 @@ exit /B 0
:Help
echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND]
-echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip]
+echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo]
echo [--download DOWNLOAD URL] [--test TARGETDIR]
echo [-h]
echo.
@@ -220,9 +213,10 @@ echo -x64 Build x64 installers
echo --build (-b) Incrementally build Python rather than rebuilding
echo --skip-build (-B) Do not build Python (just do the installers)
echo --skip-doc (-D) Do not build documentation
+echo --pgo Specify PGO command for x64 installers
+echo --skip-pgo Build x64 installers without using PGO
echo --skip-nuget Do not build Nuget packages
echo --skip-zip Do not build embeddable package
-echo --pgo Build x64 installers using PGO
echo --download Specify the full download URL for MSIs
echo --test Specify the test directory to run the installer tests
echo -h Display this help information
@@ -230,13 +224,8 @@ echo.
echo If no architecture is specified, all architectures will be built.
echo If --test is not specified, the installer tests are not run.
echo.
-echo For the --pgo option, any Python command line can be used as well as the
-echo following shortcuts:
-echo Shortcut Description
-echo default Test suite with --pgo
-echo default2 2x test suite with --pgo and randomized test order
-echo default10 10x test suite with --pgo and randomized test order
-echo pybench pybench script
+echo For the --pgo option, any Python command line can be used, or 'default' to
+echo use the default task (-m test --pgo).
echo.
echo The following substitutions will be applied to the download URL:
echo Variable Description Example
diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm
index 4d9c97a194..1c0bd08eec 100644
--- a/Tools/msi/bundle/Default.thm
+++ b/Tools/msi/bundle/Default.thm
@@ -116,10 +116,11 @@
<Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
<Image X="0" Y="0" Width="178" Height="382" ImageFile="SideBar.png"/>
- <Hypertext Name="SuccessText" X="205" Y="71" Width="-31" Height="100" FontId="3" DisablePrefix="yes"></Hypertext>
+ <Hypertext Name="SuccessText" X="205" Y="71" Width="-71" Height="150" FontId="3" DisablePrefix="yes"></Hypertext>
- <Text Name="SuccessRestartText" X="205" Y="-100" Width="-11" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
- <Button Name="LaunchButton" X="185" Y="-50" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xF" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
+ <Button Name="SuccessMaxPathButton" X="185" Y="-70" Width="-11" Height="81" TabStop="yes" FontId="3" HexStyle="0xE" HideWhenDisabled="yes">#(loc.SuccessMaxPathButton)</Button>
+
+ <Text Name="SuccessRestartText" X="205" Y="-40" Width="-11" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
<Button Name="SuccessRestartButton" X="-101" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="85" Height="27" TabStop="yes" FontId="0">#(loc.CloseButton)</Button>
</Page>
diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl
index ed792460e6..43506d6100 100644
--- a/Tools/msi/bundle/Default.wxl
+++ b/Tools/msi/bundle/Default.wxl
@@ -142,4 +142,7 @@ Please &lt;a href="https://www.bing.com/search?q=how%20to%20install%20windows%20
<String Id="FailureWS2K3OrEarlier">Windows Server 2008 SP2 or later is required to install and use [WixBundleName].
Visit &lt;a href="https://www.python.org/"&gt;python.org&lt;/a&gt; to download Python 3.4.</String>
+
+ <String Id="SuccessMaxPathButton">Disable path length limit</String>
+ <String Id="SuccessMaxPathButtonNote">Changes your machine configuration to allow programs, including Python, to bypass the 260 character "MAX_PATH" limitation.</String>
</WixLocalization>
diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
index 6a67ee211c..e88981fc3a 100644
--- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
+++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
@@ -11,10 +11,6 @@
#include "pch.h"
static const LPCWSTR PYBA_WINDOW_CLASS = L"PythonBA";
-static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget";
-static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId";
-static const LPCWSTR PYBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments";
-static const LPCWSTR PYBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden";
static const DWORD PYBA_ACQUIRE_PERCENTAGE = 30;
static const LPCWSTR PYBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion";
@@ -129,11 +125,11 @@ enum CONTROL_ID {
ID_PROGRESS_CANCEL_BUTTON,
// Success page
- ID_LAUNCH_BUTTON,
ID_SUCCESS_TEXT,
ID_SUCCESS_RESTART_TEXT,
ID_SUCCESS_RESTART_BUTTON,
ID_SUCCESS_CANCEL_BUTTON,
+ ID_SUCCESS_MAX_PATH_BUTTON,
// Failure page
ID_FAILURE_LOGFILE_LINK,
@@ -188,11 +184,11 @@ static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = {
{ ID_OVERALL_PROGRESS_TEXT, L"OverallProgressText" },
{ ID_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" },
- { ID_LAUNCH_BUTTON, L"LaunchButton" },
{ ID_SUCCESS_TEXT, L"SuccessText" },
{ ID_SUCCESS_RESTART_TEXT, L"SuccessRestartText" },
{ ID_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" },
{ ID_SUCCESS_CANCEL_BUTTON, L"SuccessCancelButton" },
+ { ID_SUCCESS_MAX_PATH_BUTTON, L"SuccessMaxPathButton" },
{ ID_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" },
{ ID_FAILURE_MESSAGE_TEXT, L"FailureMessageText" },
@@ -436,6 +432,11 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
case ID_UNINSTALL_BUTTON:
OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL);
break;
+
+ case ID_SUCCESS_MAX_PATH_BUTTON:
+ EnableMaxPathSupport();
+ ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
+ break;
}
LExit:
@@ -533,9 +534,8 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
}
void SuccessPage_Show() {
- // on the "Success" page, check if the restart or launch button should be enabled.
+ // on the "Success" page, check if the restart button should be enabled.
BOOL showRestartButton = FALSE;
- BOOL launchTargetExists = FALSE;
LOC_STRING *successText = nullptr;
HRESULT hr = S_OK;
@@ -543,8 +543,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
if (BOOTSTRAPPER_RESTART_PROMPT == _command.restart) {
showRestartButton = TRUE;
}
- } else if (ThemeControlExists(_theme, ID_LAUNCH_BUTTON)) {
- launchTargetExists = BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_PATH);
}
switch (_plannedAction) {
@@ -571,9 +569,41 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
}
}
- ThemeControlEnable(_theme, ID_LAUNCH_BUTTON, launchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < _plannedAction);
ThemeControlEnable(_theme, ID_SUCCESS_RESTART_TEXT, showRestartButton);
ThemeControlEnable(_theme, ID_SUCCESS_RESTART_BUTTON, showRestartButton);
+
+ if (_command.action != BOOTSTRAPPER_ACTION_INSTALL ||
+ !IsWindowsVersionOrGreater(10, 0, 0)) {
+ ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
+ } else {
+ DWORD dataType = 0, buffer = 0, bufferLen = sizeof(buffer);
+ HKEY hKey;
+ LRESULT res = RegOpenKeyExW(
+ HKEY_LOCAL_MACHINE,
+ L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
+ 0,
+ KEY_READ,
+ &hKey
+ );
+ if (res == ERROR_SUCCESS) {
+ res = RegQueryValueExW(hKey, L"LongPathsEnabled", nullptr, &dataType,
+ (LPBYTE)&buffer, &bufferLen);
+ RegCloseKey(hKey);
+ }
+ else {
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Failed to open SYSTEM\\CurrentControlSet\\Control\\FileSystem: error code %d", res);
+ }
+ if (res == ERROR_SUCCESS && dataType == REG_DWORD && buffer == 0) {
+ ThemeControlElevates(_theme, ID_SUCCESS_MAX_PATH_BUTTON, TRUE);
+ }
+ else {
+ if (res == ERROR_SUCCESS)
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Failed to read LongPathsEnabled value: error code %d", res);
+ else
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Hiding MAX_PATH button because it is already enabled");
+ ThemeControlEnable(_theme, ID_SUCCESS_MAX_PATH_BUTTON, FALSE);
+ }
+ }
}
void FailurePage_Show() {
@@ -626,6 +656,34 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication {
ThemeControlEnable(_theme, ID_FAILURE_RESTART_BUTTON, showRestartButton);
}
+ static void EnableMaxPathSupport() {
+ LPWSTR targetDir = nullptr, defaultDir = nullptr;
+ HRESULT hr = BalGetStringVariable(L"TargetDir", &targetDir);
+ if (FAILED(hr) || !targetDir || !targetDir[0]) {
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to get TargetDir");
+ return;
+ }
+
+ LPWSTR pythonw = nullptr;
+ StrAllocFormatted(&pythonw, L"%ls\\pythonw.exe", targetDir);
+ if (!pythonw || !pythonw[0]) {
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Failed to construct pythonw.exe path");
+ return;
+ }
+
+ LPCWSTR arguments = L"-c \"import winreg; "
+ "winreg.SetValueEx("
+ "winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, "
+ "r'SYSTEM\\CurrentControlSet\\Control\\FileSystem'), "
+ "'LongPathsEnabled', "
+ "None, "
+ "winreg.REG_DWORD, "
+ "1"
+ ")\"";
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Executing %ls %ls", pythonw, arguments);
+ HINSTANCE res = ShellExecuteW(0, L"runas", pythonw, arguments, NULL, SW_HIDE);
+ BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "return code 0x%08x", res);
+ }
public: // IBootstrapperApplication
virtual STDMETHODIMP OnStartup() {
@@ -1216,12 +1274,6 @@ public: // IBootstrapperApplication
}
virtual STDMETHODIMP_(void) OnLaunchApprovedExeComplete(__in HRESULT hrStatus, __in DWORD /*processId*/) {
- if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus) {
- //try with ShelExec next time
- OnClickLaunchButton();
- } else {
- ::PostMessageW(_hWnd, WM_CLOSE, 0, 0);
- }
}
@@ -1867,10 +1919,6 @@ private:
switch (LOWORD(wParam)) {
// Customize commands
// Success/failure commands
- case ID_LAUNCH_BUTTON:
- pBA->OnClickLaunchButton();
- return 0;
-
case ID_SUCCESS_RESTART_BUTTON: __fallthrough;
case ID_FAILURE_RESTART_BUTTON:
pBA->OnClickRestartButton();
@@ -2372,69 +2420,6 @@ private:
}
- //
- // OnClickLaunchButton - launch the app from the success page.
- //
- void OnClickLaunchButton() {
- HRESULT hr = S_OK;
- LPWSTR sczUnformattedLaunchTarget = nullptr;
- LPWSTR sczLaunchTarget = nullptr;
- LPWSTR sczLaunchTargetElevatedId = nullptr;
- LPWSTR sczUnformattedArguments = nullptr;
- LPWSTR sczArguments = nullptr;
- int nCmdShow = SW_SHOWNORMAL;
-
- hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget);
- BalExitOnFailure1(hr, "Failed to get launch target variable '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_PATH);
-
- hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget);
- BalExitOnFailure1(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget);
-
- if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID)) {
- hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId);
- BalExitOnFailure1(hr, "Failed to get launch target elevated id '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID);
- }
-
- if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_ARGUMENTS)) {
- hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments);
- BalExitOnFailure1(hr, "Failed to get launch arguments '%ls'.", PYBA_VARIABLE_LAUNCH_ARGUMENTS);
- }
-
- if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_HIDDEN)) {
- nCmdShow = SW_HIDE;
- }
-
- if (sczLaunchTargetElevatedId && !_triedToLaunchElevated) {
- _triedToLaunchElevated = TRUE;
- hr = _engine->LaunchApprovedExe(_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0);
- if (FAILED(hr)) {
- BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId);
-
- //try with ShelExec next time
- OnClickLaunchButton();
- }
- } else {
- if (sczUnformattedArguments) {
- hr = BalFormatString(sczUnformattedArguments, &sczArguments);
- BalExitOnFailure1(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments);
- }
-
- hr = ShelExec(sczLaunchTarget, sczArguments, L"open", nullptr, nCmdShow, _hWnd, nullptr);
- BalExitOnFailure1(hr, "Failed to launch target: %ls", sczLaunchTarget);
-
- ::PostMessageW(_hWnd, WM_CLOSE, 0, 0);
- }
-
- LExit:
- StrSecureZeroFreeString(sczArguments);
- ReleaseStr(sczUnformattedArguments);
- ReleaseStr(sczLaunchTargetElevatedId);
- StrSecureZeroFreeString(sczLaunchTarget);
- ReleaseStr(sczUnformattedLaunchTarget);
-
- return;
- }
-
//
// OnClickRestartButton - allows the restart and closes the app.
@@ -3157,7 +3142,6 @@ public:
_taskbarButtonCreatedMessage = UINT_MAX;
_taskbarButtonOK = FALSE;
_showingInternalUIThisPackage = FALSE;
- _triedToLaunchElevated = FALSE;
_suppressPaint = FALSE;
@@ -3242,7 +3226,6 @@ private:
UINT _taskbarButtonCreatedMessage;
BOOL _taskbarButtonOK;
BOOL _showingInternalUIThisPackage;
- BOOL _triedToLaunchElevated;
BOOL _suppressPaint;
diff --git a/Tools/msi/bundle/bundle.ico b/Tools/msi/bundle/bundle.ico
deleted file mode 100644
index 1ab629eff2..0000000000
--- a/Tools/msi/bundle/bundle.ico
+++ /dev/null
Binary files differ
diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs
index eda088404f..02a456b3fd 100644
--- a/Tools/msi/bundle/bundle.wxs
+++ b/Tools/msi/bundle/bundle.wxs
@@ -5,7 +5,7 @@
<Bundle Name="!(loc.FullProductName)"
UpgradeCode="$(var.CoreUpgradeCode)"
Version="$(var.Version)"
- IconSourceFile="bundle.ico"
+ IconSourceFile="..\..\..\PC\icons\setup.ico"
Manufacturer="!(loc.Manufacturer)"
AboutUrl="http://www.python.org/"
DisableModify="button"
diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs
index 4efad6562a..398d94a24d 100644
--- a/Tools/msi/common.wxs
+++ b/Tools/msi/common.wxs
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
+ <Property Id="ROOTREGISTRYKEY" Value="Software\Python\PythonCore" />
+ </Fragment>
+
+ <Fragment>
<Property Id="REGISTRYKEY" Value="Software\Python\PythonCore\$(var.ShortVersion)$(var.PyArchExt)$(var.PyTestExt)" />
</Fragment>
@@ -16,10 +20,12 @@
<Fragment>
<Property Id="UpgradeTable" Value="1" />
+ <?ifndef SuppressUpgradeTable ?>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" />
<UpgradeVersion Property="UPGRADE" Minimum="$(var.UpgradeMinimumVersion)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
</Upgrade>
+ <?endif ?>
<?ifdef CoreUpgradeCode ?>
<?if $(var.UpgradeCode)!=$(var.CoreUpgradeCode) ?>
@@ -40,7 +46,7 @@
<Fragment>
<!-- Include an icon for the Programs and Features dialog -->
- <Icon Id="ARPIcon" SourceFile="!(bindpath.src)PC\pycon.ico" />
+ <Icon Id="ARPIcon" SourceFile="!(bindpath.src)PC\icons\python.ico" />
<Property Id="ARPPRODUCTICON" Value="ARPIcon" />
<Property Id="ARPNOMODIFY" Value="1" />
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
@@ -57,7 +63,9 @@
<!-- Top-level directories -->
<Fragment>
<DirectoryRef Id="InstallDirectory">
- <Directory Id="DLLs" Name="DLLs" />
+ <Directory Id="DLLs" Name="DLLs">
+ <Directory Id="Catalogs" />
+ </Directory>
</DirectoryRef>
</Fragment>
diff --git a/Tools/msi/common_en-US.wxl_template b/Tools/msi/common_en-US.wxl_template
index 8d03526882..c95c271c27 100644
--- a/Tools/msi/common_en-US.wxl_template
+++ b/Tools/msi/common_en-US.wxl_template
@@ -14,4 +14,5 @@
<String Id="NoDowngrade">A newer version of !(loc.ProductName) is already installed.</String>
<String Id="IncorrectCore">An incorrect version of a prerequisite package is installed. Please uninstall any other versions of !(loc.ProductName) and try installing this again.</String>
<String Id="NoTargetDir">The TARGETDIR variable must be provided when invoking this installer.</String>
+ <String Id="ManufacturerSupportUrl">http://www.python.org/</String>
</WixLocalization>
diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj
index d26a603268..24df0f5f7a 100644
--- a/Tools/msi/exe/exe.wixproj
+++ b/Tools/msi/exe/exe.wixproj
@@ -14,6 +14,7 @@
<ItemGroup>
<Compile Include="exe.wxs" />
<Compile Include="exe_files.wxs" />
+ <Compile Include="exe_reg.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs
index 154cee5c47..03d43c6032 100644
--- a/Tools/msi/exe/exe.wxs
+++ b/Tools/msi/exe/exe.wxs
@@ -9,6 +9,7 @@
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<ComponentGroupRef Id="exe_python" Primary="yes" />
+ <ComponentGroupRef Id="exe_reg" Primary="yes" />
<ComponentGroupRef Id="exe_txt" />
<ComponentGroupRef Id="exe_icons" />
<ComponentRef Id="OptionalFeature" />
@@ -24,7 +25,6 @@
WorkingDirectory="InstallDirectory" />
<RemoveFolder Id="Remove_MenuDir" Directory="MenuDir" On="uninstall" />
<RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
- <RegistryValue Key="InstallPath\InstallGroup" Type="string" Value="!(loc.ProductName)" KeyPath="yes" />
<RegistryValue Key="InstalledFeatures" Name="Shortcuts" Type="string" Value="$(var.Version)" />
</RegistryKey>
</Component>
diff --git a/Tools/msi/exe/exe_d.wixproj b/Tools/msi/exe/exe_d.wixproj
index 27545caf7d..cf085bed4d 100644
--- a/Tools/msi/exe/exe_d.wixproj
+++ b/Tools/msi/exe/exe_d.wixproj
@@ -10,6 +10,7 @@
<ItemGroup>
<Compile Include="exe_d.wxs" />
<Compile Include="exe_files.wxs" />
+ <Compile Include="exe_reg.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
diff --git a/Tools/msi/exe/exe_en-US.wxl_template b/Tools/msi/exe/exe_en-US.wxl_template
index 577fbe51a5..1f9e290394 100644
--- a/Tools/msi/exe/exe_en-US.wxl_template
+++ b/Tools/msi/exe/exe_en-US.wxl_template
@@ -4,4 +4,5 @@
<String Id="ShortDescriptor">executable</String>
<String Id="ShortcutName">Python {{ShortVersion}} ({{Bitness}})</String>
<String Id="ShortcutDescription">Launches the !(loc.ProductName) interpreter.</String>
+ <String Id="SupportUrl">http://www.python.org/</String>
</WixLocalization>
diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs
index 9e47b5d980..01385874fa 100644
--- a/Tools/msi/exe/exe_files.wxs
+++ b/Tools/msi/exe/exe_files.wxs
@@ -28,6 +28,9 @@
</Component>
<Component Id="pythonw.exe" Directory="InstallDirectory" Guid="$(var.PythonwExeComponentGuid)">
<File Name="pythonw.exe" KeyPath="yes" />
+ <RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
+ <RegistryValue Key="InstallPath" Name="WindowedExecutablePath" Type="string" Value="[#pythonw.exe]" KeyPath="no" />
+ </RegistryKey>
</Component>
<Component Id="vcruntime140.dll" Directory="InstallDirectory" Guid="*">
<File Name="vcruntime140.dll" Source="!(bindpath.redist)vcruntime140.dll" KeyPath="yes" />
@@ -66,10 +69,13 @@
<Fragment>
<ComponentGroup Id="exe_icons">
<Component Id="py.ico" Directory="DLLs" Guid="*">
- <File Name="py.ico" Source="!(bindpath.src)PC\py.ico" KeyPath="yes" />
+ <File Name="py.ico" Source="!(bindpath.src)PC\icons\py.ico" KeyPath="yes" />
</Component>
<Component Id="pyc.ico" Directory="DLLs" Guid="*">
- <File Name="pyc.ico" Source="!(bindpath.src)PC\pyc.ico" KeyPath="yes" />
+ <File Name="pyc.ico" Source="!(bindpath.src)PC\icons\pyc.ico" KeyPath="yes" />
+ </Component>
+ <Component Id="pyd.ico" Directory="DLLs" Guid="*">
+ <File Name="pyd.ico" Source="!(bindpath.src)PC\icons\pyd.ico" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
diff --git a/Tools/msi/exe/exe_pdb.wixproj b/Tools/msi/exe/exe_pdb.wixproj
index 4f4c869926..bf1213e9d4 100644
--- a/Tools/msi/exe/exe_pdb.wixproj
+++ b/Tools/msi/exe/exe_pdb.wixproj
@@ -10,6 +10,7 @@
<ItemGroup>
<Compile Include="exe_pdb.wxs" />
<Compile Include="exe_files.wxs" />
+ <Compile Include="exe_reg.wxs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="*.wxl" />
diff --git a/Tools/msi/exe/exe_reg.wxs b/Tools/msi/exe/exe_reg.wxs
new file mode 100644
index 0000000000..4443c21554
--- /dev/null
+++ b/Tools/msi/exe/exe_reg.wxs
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <Fragment>
+ <PropertyRef Id="ROOTREGISTRYKEY" />
+ <PropertyRef Id="REGISTRYKEY" />
+
+ <ComponentGroup Id="exe_reg">
+ <Component Id="CommonPythonRegistration" Directory="InstallDirectory" Guid="$(var.CommonPythonRegComponentGuid)">
+ <RegistryKey Root="HKMU" Key="[ROOTREGISTRYKEY]">
+ <RegistryValue Name="DisplayName" Type="string" Value="!(loc.Manufacturer)" KeyPath="yes" />
+ <RegistryValue Name="SupportUrl" Type="string" Value="!(loc.ManufacturerSupportUrl)" KeyPath="no" />
+ </RegistryKey>
+ </Component>
+ <Component Id="PythonRegistration" Directory="InstallDirectory" Guid="$(var.PythonRegComponentGuid)">
+ <RegistryKey Root="HKMU" Key="[REGISTRYKEY]">
+ <RegistryValue Name="DisplayName" Type="string" Value="!(loc.ShortcutName)" KeyPath="yes" />
+ <RegistryValue Name="SupportUrl" Type="string" Value="!(loc.SupportUrl)" KeyPath="no" />
+ <RegistryValue Name="Version" Type="string" Value="$(var.LongVersion)" KeyPath="no" />
+ <RegistryValue Name="SysVersion" Type="string" Value="$(var.ShortVersion)" KeyPath="no" />
+ <RegistryValue Name="SysArchitecture" Type="string" Value="$(var.PlatformArchitecture)" KeyPath="no" />
+ </RegistryKey>
+ </Component>
+ </ComponentGroup>
+ </Fragment>
+</Wix>
diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj
index 01a9dcb29e..8935ce88a7 100644
--- a/Tools/msi/launcher/launcher.wixproj
+++ b/Tools/msi/launcher/launcher.wixproj
@@ -5,7 +5,7 @@
<SchemaVersion>2.0</SchemaVersion>
<OutputName>launcher</OutputName>
<OutputType>Package</OutputType>
- <DefineConstants>UpgradeCode=1B68A0EC-4DD3-5134-840E-73854B0863F1;$(DefineConstants)</DefineConstants>
+ <DefineConstants>UpgradeCode=1B68A0EC-4DD3-5134-840E-73854B0863F1;SuppressUpgradeTable=1;$(DefineConstants)</DefineConstants>
<IgnoreCommonWxlTemplates>true</IgnoreCommonWxlTemplates>
<SuppressICEs>ICE80</SuppressICEs>
</PropertyGroup>
diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs
index ebd875cd9a..7de131a3ed 100644
--- a/Tools/msi/launcher/launcher.wxs
+++ b/Tools/msi/launcher/launcher.wxs
@@ -5,7 +5,10 @@
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<Property Id="Suppress_TARGETDIR_Check" Value="1" />
- <PropertyRef Id="ARPPRODUCTICON" />
+ <Icon Id="ARPIcon" SourceFile="!(bindpath.src)PC\icons\launcher.ico" />
+ <Property Id="ARPPRODUCTICON" Value="ARPIcon" />
+ <Property Id="ARPNOMODIFY" Value="1" />
+ <Property Id="DISABLEADVTSHORTCUTS" Value="1" />
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<ComponentGroupRef Id="launcher_exe" Primary="yes" />
@@ -26,18 +29,21 @@
<Custom Before="SetLauncherInstallDirectoryLM" Action="SetLauncherInstallDirectoryCU">NOT Installed AND NOT ALLUSERS=1</Custom>
<Custom Before="CostFinalize" Action="SetLauncherInstallDirectoryLM">NOT Installed AND ALLUSERS=1</Custom>
- <RemoveExistingProducts After="InstallValidate">UPGRADE or REMOVE_350_LAUNCHER</RemoveExistingProducts>
+ <RemoveExistingProducts After="InstallValidate">UPGRADE or REMOVE_350_LAUNCHER or REMOVE_360A1_LAUNCHER</RemoveExistingProducts>
</InstallExecuteSequence>
+ <!-- Upgrade all versions of the launcher -->
+ <Upgrade Id="$(var.UpgradeCode)">
+ <UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" />
+ <UpgradeVersion Property="UPGRADE" Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" />
+ </Upgrade>
<!-- Python 3.5.0 shipped with a different UpgradeCode -->
<Upgrade Id="A71530B9-E89D-53DB-9C2D-C6D7551876D8">
<UpgradeVersion Minimum="0.0.0.0" Property="REMOVE_350_LAUNCHER" />
</Upgrade>
<!-- Python 3.6.0a1 shipped with a different UpgradeCode -->
<Upgrade Id="394750C0-7880-5A8F-999F-933965FBCFB4">
- <UpgradeVersion Maximum="$(var.Version)" Property="REMOVE_360A1_LAUNCHER" />
- <UpgradeVersion Minimum="$(var.Version)" Property="BLOCK_360A1_LAUNCHER" />
+ <UpgradeVersion Minimum="0.0.0.0" Property="REMOVE_360A1_LAUNCHER" />
</Upgrade>
- <Condition Message="!(loc.NoDowngrade)">Installed OR NOT BLOCK_360A1_LAUNCHER</Condition>
</Product>
</Wix>
diff --git a/Tools/msi/launcher/launcher_en-US.wxl b/Tools/msi/launcher/launcher_en-US.wxl
index e4c1aaa9fa..a7e3827c52 100644
--- a/Tools/msi/launcher/launcher_en-US.wxl
+++ b/Tools/msi/launcher/launcher_en-US.wxl
@@ -11,6 +11,7 @@
<String Id="PythonFileDescription">Python File</String>
<String Id="PythonNoConFileDescription">Python File (no console)</String>
<String Id="PythonCompiledFileDescription">Compiled Python File</String>
+ <String Id="PythonExtensionDescription">Python Extension Module</String>
<String Id="PythonArchiveFileDescription">Python Zip Application File</String>
<String Id="PythonNoConArchiveFileDescription">Python Zip Application File (no console)</String>
</WixLocalization>
diff --git a/Tools/msi/launcher/launcher_reg.wxs b/Tools/msi/launcher/launcher_reg.wxs
index 981961ab0d..dace97ee58 100644
--- a/Tools/msi/launcher/launcher_reg.wxs
+++ b/Tools/msi/launcher/launcher_reg.wxs
@@ -27,14 +27,18 @@
</ProgId>
<RegistryValue Root="HKCR" Key="Python.CompiledFile\shellex\DropHandler" Value="{BEA218D2-6950-497B-9434-61683EC065FE}" Type="string" />
- <ProgId Id="Python.ArchiveFile" Description="!(loc.PythonArchiveFileDescription)" Advertise="no" Icon="py.exe" IconIndex="1">
+ <ProgId Id="Python.Extension" Description="!(loc.PythonExtensionDescription)" Advertise="no" Icon="py.exe" IconIndex="3">
+ <Extension Id="pyd" />
+ </ProgId>
+
+ <ProgId Id="Python.ArchiveFile" Description="!(loc.PythonArchiveFileDescription)" Advertise="no" Icon="py.exe" IconIndex="5">
<Extension Id="pyz" ContentType="application/x-zip-compressed">
<Verb Id="open" TargetFile="py.exe" Argument="&quot;%L&quot; %*" />
</Extension>
</ProgId>
<RegistryValue Root="HKCR" Key="Python.ArchiveFile\shellex\DropHandler" Value="{BEA218D2-6950-497B-9434-61683EC065FE}" Type="string" />
- <ProgId Id="Python.NoConArchiveFile" Description="!(loc.PythonNoConArchiveFileDescription)" Advertise="no" Icon="py.exe" IconIndex="1">
+ <ProgId Id="Python.NoConArchiveFile" Description="!(loc.PythonNoConArchiveFileDescription)" Advertise="no" Icon="py.exe" IconIndex="5">
<Extension Id="pyzw" ContentType="application/x-zip-compressed">
<Verb Id="open" TargetFile="pyw.exe" Argument="&quot;%L&quot; %*" />
</Extension>
diff --git a/Tools/msi/lib/lib.wixproj b/Tools/msi/lib/lib.wixproj
index 64e58787b8..26311ea327 100644
--- a/Tools/msi/lib/lib.wixproj
+++ b/Tools/msi/lib/lib.wixproj
@@ -27,6 +27,7 @@
<TargetBase>$(PySourcePath)Lib</TargetBase>
<Target_>Lib\</Target_>
<Group>lib_py</Group>
+ <IncludeInCat>true</IncludeInCat>
</InstallFiles>
</ItemGroup>
diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs
index 2b04bcb304..2a3b9ecfee 100644
--- a/Tools/msi/lib/lib.wxs
+++ b/Tools/msi/lib/lib.wxs
@@ -11,6 +11,7 @@
<ComponentGroupRef Id="lib_py" />
<ComponentGroupRef Id="lib_files" />
<ComponentGroupRef Id="lib_extensions" />
+ <ComponentGroupRef Id="lib_cat" />
<ComponentRef Id="OptionalFeature" />
</Feature>
</Product>
diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs
index a992784939..a83f544db6 100644
--- a/Tools/msi/lib/lib_files.wxs
+++ b/Tools/msi/lib/lib_files.wxs
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
- <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3 ?>
+ <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3;_asyncio ?>
<Fragment>
<ComponentGroup Id="lib_extensions">
<?foreach ext in $(var.exts)?>
@@ -63,16 +63,17 @@
<RegistryValue Key="PythonPath" Type="string" Value="[Lib];[DLLs]" />
</RegistryKey>
</Component>
- <Component Id="Lib_site_packages_README" Directory="Lib_site_packages" Guid="*">
- <File Id="Lib_site_packages_README" Name="README.txt" Source="!(bindpath.src)Lib\site-packages\README" KeyPath="yes" />
- </Component>
<Component Id="Lib2to3_pickle_remove" Directory="Lib_lib2to3" Guid="$(var.RemoveLib2to3PickleComponentGuid)">
<RemoveFile Id="Lib2to3_pickle_remove_files" Name="*.pickle" On="uninstall" />
<RemoveFolder Id="Lib2to3_pickle_remove_folder" On="uninstall" />
</Component>
</ComponentGroup>
- <DirectoryRef Id="Lib">
- <Directory Id="Lib_site_packages" Name="site-packages" />
- </DirectoryRef>
+ </Fragment>
+ <Fragment>
+ <ComponentGroup Id="lib_cat">
+ <Component Id="lib_cat" Directory="Catalogs" Guid="*">
+ <File Name="python_lib.cat" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
</Fragment>
</Wix>
diff --git a/Tools/msi/make_zip.proj b/Tools/msi/make_zip.proj
index 1af6dd2868..f78e6ffa28 100644
--- a/Tools/msi/make_zip.proj
+++ b/Tools/msi/make_zip.proj
@@ -16,7 +16,7 @@
<TargetPath>$(OutputPath)\$(TargetName)$(TargetExt)</TargetPath>
<CleanCommand>rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)"</CleanCommand>
<Arguments>"$(PythonExe)" "$(MSBuildThisFileDirectory)\make_zip.py"</Arguments>
- <Arguments>$(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -b "$(BuildPath.TrimEnd('\'))"</Arguments>
+ <Arguments>$(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -a $(ArchName)</Arguments>
<Environment>set DOC_FILENAME=python$(PythonVersion).chm
set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT</Environment>
</PropertyGroup>
diff --git a/Tools/msi/make_zip.py b/Tools/msi/make_zip.py
index 9db96cb271..8dbe83e4f4 100644
--- a/Tools/msi/make_zip.py
+++ b/Tools/msi/make_zip.py
@@ -20,6 +20,7 @@ DEBUG_FILES = {
'_ctypes_test',
'_testbuffer',
'_testcapi',
+ '_testconsole',
'_testimportmultiple',
'_testmultiphase',
'xxlimited',
@@ -42,11 +43,16 @@ EXCLUDE_FILE_FROM_LIBRARY = {
}
EXCLUDE_FILE_FROM_LIBS = {
+ 'liblzma',
'ssleay',
'libeay',
'python3stub',
}
+EXCLUDED_FILES = {
+ 'pyshellext',
+}
+
def is_not_debug(p):
if DEBUG_RE.search(p.name):
return False
@@ -54,7 +60,7 @@ def is_not_debug(p):
if TKTCL_RE.search(p.name):
return False
- return p.stem.lower() not in DEBUG_FILES
+ return p.stem.lower() not in DEBUG_FILES and p.stem.lower() not in EXCLUDED_FILES
def is_not_debug_or_python(p):
return is_not_debug(p) and not PYTHON_DLL_RE.search(p.name)
@@ -64,8 +70,6 @@ def include_in_lib(p):
if p.is_dir():
if name in EXCLUDE_FROM_LIBRARY:
return False
- if name.startswith('plat-'):
- return False
if name == 'test' and p.parts[-2].lower() == 'lib':
return False
if name in {'test', 'tests'} and p.parts[-3].lower() == 'lib':
@@ -90,25 +94,27 @@ def include_in_tools(p):
return p.suffix.lower() in {'.py', '.pyw', '.txt'}
+BASE_NAME = 'python{0.major}{0.minor}'.format(sys.version_info)
+
FULL_LAYOUT = [
- ('/', '$build', 'python.exe', is_not_debug),
- ('/', '$build', 'pythonw.exe', is_not_debug),
- ('/', '$build', 'python{0.major}.dll'.format(sys.version_info), is_not_debug),
- ('/', '$build', 'python{0.major}{0.minor}.dll'.format(sys.version_info), is_not_debug),
- ('DLLs/', '$build', '*.pyd', is_not_debug),
- ('DLLs/', '$build', '*.dll', is_not_debug_or_python),
+ ('/', 'PCBuild/$arch', 'python.exe', is_not_debug),
+ ('/', 'PCBuild/$arch', 'pythonw.exe', is_not_debug),
+ ('/', 'PCBuild/$arch', 'python{}.dll'.format(sys.version_info.major), is_not_debug),
+ ('/', 'PCBuild/$arch', '{}.dll'.format(BASE_NAME), is_not_debug),
+ ('DLLs/', 'PCBuild/$arch', '*.pyd', is_not_debug),
+ ('DLLs/', 'PCBuild/$arch', '*.dll', is_not_debug_or_python),
('include/', 'include', '*.h', None),
('include/', 'PC', 'pyconfig.h', None),
('Lib/', 'Lib', '**/*', include_in_lib),
- ('libs/', '$build', '*.lib', include_in_libs),
+ ('libs/', 'PCBuild/$arch', '*.lib', include_in_libs),
('Tools/', 'Tools', '**/*', include_in_tools),
]
EMBED_LAYOUT = [
- ('/', '$build', 'python*.exe', is_not_debug),
- ('/', '$build', '*.pyd', is_not_debug),
- ('/', '$build', '*.dll', is_not_debug),
- ('python{0.major}{0.minor}.zip'.format(sys.version_info), 'Lib', '**/*', include_in_lib),
+ ('/', 'PCBuild/$arch', 'python*.exe', is_not_debug),
+ ('/', 'PCBuild/$arch', '*.pyd', is_not_debug),
+ ('/', 'PCBuild/$arch', '*.dll', is_not_debug),
+ ('{}.zip'.format(BASE_NAME), 'Lib', '**/*', include_in_lib),
]
if os.getenv('DOC_FILENAME'):
@@ -172,15 +178,15 @@ def main():
parser.add_argument('-o', '--out', metavar='file', help='The name of the output archive', type=Path, default=None)
parser.add_argument('-t', '--temp', metavar='dir', help='A directory to temporarily extract files into', type=Path, default=None)
parser.add_argument('-e', '--embed', help='Create an embedding layout', action='store_true', default=False)
- parser.add_argument('-b', '--build', help='Specify the build directory', type=Path)
+ parser.add_argument('-a', '--arch', help='Specify the architecture to use (win32/amd64)', type=str, default="win32")
ns = parser.parse_args()
source = ns.source or (Path(__file__).resolve().parent.parent.parent)
out = ns.out
- build = ns.build
+ arch = ns.arch
assert isinstance(source, Path)
assert not out or isinstance(out, Path)
- assert isinstance(build, Path)
+ assert isinstance(arch, str)
if ns.temp:
temp = ns.temp
@@ -203,10 +209,7 @@ def main():
try:
for t, s, p, c in layout:
- if s == '$build':
- fs = build
- else:
- fs = source / s
+ fs = source / s.replace("$arch", arch)
files = rglob(fs, p, c)
extra_files = []
if s == 'Lib' and p == '**/*':
@@ -217,8 +220,13 @@ def main():
copied = copy_to_layout(temp / t.rstrip('/'), chain(files, extra_files))
print('Copied {} files'.format(copied))
- with open(str(temp / 'pyvenv.cfg'), 'w') as f:
- print('applocal = true', file=f)
+ if ns.embed:
+ with open(str(temp / (BASE_NAME + '._pth')), 'w') as f:
+ print(BASE_NAME + '.zip', file=f)
+ print('.', file=f)
+ print('', file=f)
+ print('# Uncomment to run site.main() automatically', file=f)
+ print('#import site', file=f)
if out:
total = copy_to_layout(out, rglob(temp, '**/*', None))
diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props
index 0cf7c7779f..60abba1f7b 100644
--- a/Tools/msi/msi.props
+++ b/Tools/msi/msi.props
@@ -11,6 +11,7 @@
<Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
<Platform Condition="'$(Platform)' == ''">x86</Platform>
<InstallScope Condition="'$(InstallScope)' != 'perMachine'">perUser</InstallScope>
+ <_MakeCatCommand Condition="'$(_MakeCatCommand)' == ''">makecat</_MakeCatCommand>
</PropertyGroup>
<Import Project="wix.props" />
@@ -69,6 +70,8 @@
<PropertyGroup>
<Bitness>32-bit</Bitness>
<Bitness Condition="$(Platform) == 'x64'">64-bit</Bitness>
+ <PlatformArchitecture>32bit</PlatformArchitecture>
+ <PlatformArchitecture Condition="$(Platform) == 'x64'">64bit</PlatformArchitecture>
<DefineConstants>
$(DefineConstants);
Version=$(InstallerVersion);
@@ -79,6 +82,7 @@
UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0;
NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0;
Bitness=$(Bitness);
+ PlatformArchitecture=$(PlatformArchitecture);
PyDebugExt=$(PyDebugExt);
PyArchExt=$(PyArchExt);
PyTestExt=$(PyTestExt);
@@ -100,6 +104,7 @@
<Group>generated_filelist</Group>
<Condition></Condition>
<DiskId></DiskId>
+ <IncludeInCat>false</IncludeInCat>
</InstallFiles>
<LinkerBindInputPaths>
<Visible>false</Visible>
@@ -155,6 +160,12 @@
<_Uuid Include="RemoveLib2to3PickleComponentGuid">
<Uri>lib2to3/pickles</Uri>
</_Uuid>
+ <_Uuid Include="CommonPythonRegComponentGuid">
+ <Uri>registry</Uri>
+ </_Uuid>
+ <_Uuid Include="PythonRegComponentGuid">
+ <Uri>registry/$(OutputName)</Uri>
+ </_Uuid>
</ItemGroup>
<Target Name="_GenerateGuids" AfterTargets="PrepareForBuild" Condition="$(TargetName) != 'launcher'">
<PropertyGroup>
diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets
index 86be35badb..9283a1ed6c 100644
--- a/Tools/msi/msi.targets
+++ b/Tools/msi/msi.targets
@@ -12,8 +12,10 @@
<_Source>%(Source)$([msbuild]::MakeRelative(%(SourceBase), %(FullPath)))</_Source>
<_Target>%(Target_)$([msbuild]::MakeRelative(%(TargetBase), %(FullPath)))</_Target>
</InstallFiles>
+
+ <_CatalogFiles Include="@(InstallFiles)" Condition="%(InstallFiles.IncludeInCat) and ''!=$([System.IO.File]::ReadAllText(%(InstallFiles.FullPath)))" />
</ItemGroup>
-
+
<WriteLinesToFile File="$(_FileListTarget)" Lines="@(InstallFiles->'&quot;%(_Source)&quot;,&quot;%(_Target)&quot;,&quot;%(Group)&quot;,&quot;%(DiskId)&quot;,&quot;%(Condition)&quot;')" Overwrite="true" />
<Exec Command='"$(PythonExe)" csv_to_wxs.py "$(_FileListTarget)" "$(_InstallFilesTarget)"'
WorkingDirectory="$(MSBuildThisFileDirectory)" />
@@ -24,6 +26,35 @@
</ItemGroup>
</Target>
+ <Target Name="GenerateCatalog" AfterTargets="ProcessInstallFiles" Condition="'@(_CatalogFiles)' != ''">
+ <PropertyGroup>
+ <_CatFileSourceTarget>$(IntermediateOutputPath)$(MSBuildProjectName).cdf</_CatFileSourceTarget>
+ <_CatFileTarget>$(IntermediateOutputPath)python_$(MSBuildProjectName).cat</_CatFileTarget>
+ <_CatFile>[CatalogHeader]
+Name=$([System.IO.Path]::GetFileName($(_CatFileTarget)))
+ResultDir=$([System.IO.Path]::GetDirectoryName($(_CatFileTarget)))
+PublicVersion=1
+CatalogVersion=2
+HashAlgorithms=SHA256
+PageHashes=false
+EncodingType=
+
+[CatalogFiles]
+@(_CatalogFiles->'&lt;HASH&gt;%(Filename)%(Extension)=%(FullPath)','
+')
+</_CatFile>
+ </PropertyGroup>
+
+ <WriteLinesToFile File="$(_CatFileSourceTarget)" Lines="$(_CatFile)" Overwrite="true" />
+ <Exec Command='$(_MakeCatCommand) "$(_CatFileSourceTarget)"' WorkingDirectory="$(MSBuildThisFileDirectory)" />
+ <Exec Command='$(_SignCommand) "$(_CatFileTarget)"' WorkingDirectory="$(MSBuildThisFileDirectory)"
+ Condition="Exists($(_CatFileTarget)) and '$(_SignCommand)' != ''" />
+
+ <ItemGroup>
+ <FileWrites Include="$(_CatFileSourceTarget);$(_CatFileTarget)" />
+ </ItemGroup>
+ </Target>
+
<Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild" Inputs="@(WxlTemplate);$(PySourcePath)include\patchlevel.h" Outputs="$(IntermediateOutputPath)%(Filename).wxl">
<PropertyGroup Condition="'@(WxlTemplate)' != ''">
<_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)$(PyTestExt)`).Replace(`{{LongVersion}}`, `$(PythonVersion)$(PyTestExt)`).Replace(`{{Bitness}}`, `$(Bitness)`))</_Content>
diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs
index e803aa0f55..82a9115f75 100644
--- a/Tools/msi/test/test_files.wxs
+++ b/Tools/msi/test/test_files.wxs
@@ -1,77 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+ <?define exts=_testcapi;_ctypes_test;_testbuffer;_testimportmultiple;_testmultiphase;_testconsole ?>
<Fragment>
<ComponentGroup Id="test_extensions">
- <Component Id="_testcapi.pyd" Directory="DLLs" Guid="*">
- <File Id="_testcapi.pyd" Name="_testcapi.pyd" KeyPath="yes" />
- </Component>
- <Component Id="_ctypes_test.pyd" Directory="DLLs" Guid="*">
- <File Id="_ctypes_test.pyd" Name="_ctypes_test.pyd" KeyPath="yes" />
- </Component>
- <Component Id="_testbuffer.pyd" Directory="DLLs" Guid="*">
- <File Id="_testbuffer.pyd" Name="_testbuffer.pyd" KeyPath="yes" />
- </Component>
- <Component Id="_testimportmultiple.pyd" Directory="DLLs" Guid="*">
- <File Id="_testimportmultiple.pyd" Name="_testimportmultiple.pyd" KeyPath="yes" />
- </Component>
- <Component Id="_testmultiphase.pyd" Directory="DLLs" Guid="*">
- <File Id="_testmultiphase.pyd" Name="_testmultiphase.pyd" KeyPath="yes" />
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext).pyd" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext).pyd" KeyPath="yes" />
</Component>
+
+ <?endforeach ?>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="test_extensions_symbols">
- <Component Id="_testcapi.pdb" Directory="DLLs" Guid="*">
- <File Id="_testcapi.pdb" Name="_testcapi.pdb" />
- </Component>
- <Component Id="_ctypes_test.pdb" Directory="DLLs" Guid="*">
- <File Id="_ctypes_test.pdb" Name="_ctypes_test.pdb" />
- </Component>
- <Component Id="_testbuffer.pdb" Directory="DLLs" Guid="*">
- <File Id="_testbuffer.pdb" Name="_testbuffer.pdb" />
- </Component>
- <Component Id="_testimportmultiple.pdb" Directory="DLLs" Guid="*">
- <File Id="_testimportmultiple.pdb" Name="_testimportmultiple.pdb" />
- </Component>
- <Component Id="_testmultiphase.pdb" Directory="DLLs" Guid="*">
- <File Id="_testmultiphase.pdb" Name="_testmultiphase.pdb" />
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext).pdb" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext).pdb" />
</Component>
+
+ <?endforeach ?>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="test_extensions_d">
- <Component Id="_testcapi_d.pyd" Directory="DLLs" Guid="*">
- <File Id="_testcapi_d.pyd" Name="_testcapi_d.pyd" />
- </Component>
- <Component Id="_ctypes_test_d.pyd" Directory="DLLs" Guid="*">
- <File Id="_ctypes_test_d.pyd" Name="_ctypes_test_d.pyd" />
- </Component>
- <Component Id="_testbuffer_d.pyd" Directory="DLLs" Guid="*">
- <File Id="_testbuffer_d.pyd" Name="_testbuffer_d.pyd" />
- </Component>
- <Component Id="_testimportmultiple_d.pyd" Directory="DLLs" Guid="*">
- <File Id="_testimportmultiple_d.pyd" Name="_testimportmultiple_d.pyd" />
- </Component>
- <Component Id="_testmultiphase_d.pyd" Directory="DLLs" Guid="*">
- <File Id="_testmultiphase_d.pyd" Name="_testmultiphase_d.pyd" />
- </Component>
- <Component Id="_testcapi_d.pdb" Directory="DLLs" Guid="*">
- <File Id="_testcapi_d.pdb" Name="_testcapi_d.pdb" />
- </Component>
- <Component Id="_ctypes_test_d.pdb" Directory="DLLs" Guid="*">
- <File Id="_ctypes_test_d.pdb" Name="_ctypes_test_d.pdb" />
- </Component>
- <Component Id="_testbuffer_d.pdb" Directory="DLLs" Guid="*">
- <File Id="_testbuffer_d.pdb" Name="_testbuffer_d.pdb" />
- </Component>
- <Component Id="_testimportmultiple_d.pdb" Directory="DLLs" Guid="*">
- <File Id="_testimportmultiple_d.pdb" Name="_testimportmultiple_d.pdb" />
+ <?foreach ext in $(var.exts)?>
+
+ <Component Id="$(var.ext)_d.pyd" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext)_d.pyd" />
</Component>
- <Component Id="_testmultiphase_d.pdb" Directory="DLLs" Guid="*">
- <File Id="_testmultiphase_d.pdb" Name="_testmultiphase_d.pdb" />
+ <Component Id="$(var.ext)_d.pdb" Directory="DLLs" Guid="*">
+ <File Name="$(var.ext)_d.pdb" />
</Component>
+
+ <?endforeach ?>
</ComponentGroup>
</Fragment>
</Wix>
diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj
index f43cf3309e..b7fc41ee92 100644
--- a/Tools/msi/tools/tools.wixproj
+++ b/Tools/msi/tools/tools.wixproj
@@ -36,6 +36,7 @@
<TargetBase>$(PySourcePath)</TargetBase>
<Target_></Target_>
<Group>tools_py</Group>
+ <IncludeInCat>true</IncludeInCat>
</InstallFiles>
</ItemGroup>
diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs
index 8f8418a46c..7a805d0612 100644
--- a/Tools/msi/tools/tools.wxs
+++ b/Tools/msi/tools/tools.wxs
@@ -9,6 +9,7 @@
<Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)">
<ComponentGroupRef Id="tools_py" />
<ComponentGroupRef Id="tools_scripts" />
+ <ComponentGroupRef Id="tools_cat" />
<ComponentRef Id="OptionalFeature" />
</Feature>
</Product>
diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs
index 3ae0db2e1f..9c76b1b444 100644
--- a/Tools/msi/tools/tools_files.wxs
+++ b/Tools/msi/tools/tools_files.wxs
@@ -13,4 +13,11 @@
</Component>
</ComponentGroup>
</Fragment>
+ <Fragment>
+ <ComponentGroup Id="tools_cat">
+ <Component Id="tools_cat" Directory="Catalogs" Guid="*">
+ <File Name="python_tools.cat" KeyPath="yes" />
+ </Component>
+ </ComponentGroup>
+ </Fragment>
</Wix>