diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index 6efd614770b..b62faf65fad 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -11,6 +11,11 @@ Removing Uninstall + You will be prompted for Administrator privileges to install a C Runtime Library update (KB2999226). + + +Continue? + &Cancel &Close Install [WixBundleName] diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index 5eda3f75caf..d090443cf60 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -10,8 +10,6 @@ #include "pch.h" -static const LPCWSTR WIXBUNDLE_VARIABLE_ELEVATED = L"WixBundleElevated"; - 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"; @@ -232,7 +230,7 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { void OnCommand(CONTROL_ID id) { LPWSTR defaultDir = nullptr; LPWSTR targetDir = nullptr; - LONGLONG elevated; + LONGLONG elevated, crtInstalled; BOOL checked; WCHAR wzPath[MAX_PATH] = { }; BROWSEINFOW browseInfo = { }; @@ -320,6 +318,10 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { ReleaseStr(targetDir); BalExitOnFailure(hr, "Failed to set install target directory"); + if (!QueryElevateForCrtInstall()) { + break; + } + OnPlan(BOOTSTRAPPER_ACTION_INSTALL); break; @@ -352,6 +354,11 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { ReleaseStr(targetDir); } + checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX); + if (!checked && !QueryElevateForCrtInstall()) { + break; + } + OnPlan(_command.action); break; @@ -2311,6 +2318,75 @@ private: } } + BOOL IsCrtInstalled() { + if (_crtInstalledToken > 0) { + return TRUE; + } else if (_crtInstalledToken == 0) { + return FALSE; + } + + // Check whether at least CRT v10.0.9920.0 is available. + // It should only be installed as a Windows Update package, which means + // we don't need to worry about 32-bit/64-bit. + // However, since the WU package does not include vcruntime140.dll, we + // still install that ourselves. + LPCWSTR crtFile = L"api-ms-win-crt-runtime-l1-1-0.dll"; + + DWORD cbVer = GetFileVersionInfoSizeW(crtFile, nullptr); + if (!cbVer) { + _crtInstalledToken = 0; + return FALSE; + } + + void *pData = malloc(cbVer); + if (!pData) { + _crtInstalledToken = 0; + return FALSE; + } + + if (!GetFileVersionInfoW(crtFile, 0, cbVer, pData)) { + free(pData); + _crtInstalledToken = 0; + return FALSE; + } + + VS_FIXEDFILEINFO *ffi; + UINT cb; + BOOL result = FALSE; + + if (VerQueryValueW(pData, L"\\", (LPVOID*)&ffi, &cb) && + ffi->dwFileVersionMS == 0x000A0000 && ffi->dwFileVersionLS >= 0x26C00000) { + result = TRUE; + } + + free(pData); + _crtInstalledToken = result ? 1 : 0; + return result; + } + + BOOL QueryElevateForCrtInstall() { + // Called to prompt the user that even though they think they won't need + // to elevate, they actually will because of the CRT install. + if (IsCrtInstalled()) { + // CRT is already installed - no need to prompt + return TRUE; + } + + LONGLONG elevated; + HRESULT hr = BalGetNumericVariable(L"WixBundleElevated", &elevated); + if (SUCCEEDED(hr) && elevated) { + // Already elevated - no need to prompt + return TRUE; + } + + LOC_STRING *locStr; + hr = LocGetString(_wixLoc, L"#(loc.ElevateForCRTInstall)", &locStr); + if (FAILED(hr)) { + BalLogError(hr, "Failed to get ElevateForCRTInstall string"); + return FALSE; + } + return ::MessageBoxW(_hWnd, locStr->wzText, _theme->sczCaption, MB_YESNO) != IDNO; + } HRESULT EvaluateConditions() { HRESULT hr = S_OK; @@ -2498,6 +2574,8 @@ public: } } + pEngine->SetVariableNumeric(L"CRTInstalled", IsCrtInstalled() ? 1 : 0); + _wixLoc = nullptr; memset(&_bundle, 0, sizeof(_bundle)); memset(&_conditions, 0, sizeof(_conditions)); @@ -2525,6 +2603,8 @@ public: _suppressRepair = FALSE; _modifying = FALSE; + _crtInstalledToken = -1; + _overridableVariables = nullptr; _taskbarList = nullptr; _taskbarButtonCreatedMessage = UINT_MAX; @@ -2606,6 +2686,8 @@ private: BOOL _suppressRepair; BOOL _modifying; + int _crtInstalledToken; + STRINGDICT_HANDLE _overridableVariables; ITaskbarList3* _taskbarList; diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets index 7697af726bd..cc7e4450238 100644 --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -10,6 +10,8 @@ $(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber) $(OutputName)-amd64 $(OutputName)-$(OutputSuffix) + $(OutputName)-d + $(OutputName) $(OutputPath)en-us\ $(OutputPath) @@ -43,6 +45,7 @@ + diff --git a/Tools/msi/bundle/postinstall_en-US.wxl_template b/Tools/msi/bundle/bundle.wxl similarity index 51% rename from Tools/msi/bundle/postinstall_en-US.wxl_template rename to Tools/msi/bundle/bundle.wxl index 5f54aefb3dd..684e0dac4e3 100644 --- a/Tools/msi/bundle/postinstall_en-US.wxl_template +++ b/Tools/msi/bundle/bundle.wxl @@ -1,4 +1,5 @@ - Precompiling standard library + C Runtime Update (KB2999226) + Precompiling standard library diff --git a/Tools/msi/bundle/packagegroups/crt.wxs b/Tools/msi/bundle/packagegroups/crt.wxs index e19b4f9c405..b0797009f63 100644 --- a/Tools/msi/bundle/packagegroups/crt.wxs +++ b/Tools/msi/bundle/packagegroups/crt.wxs @@ -2,6 +2,11 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/crt/crt.wixproj b/Tools/msi/crt/crt.wixproj index 8389b3a09f3..75295ba4209 100644 --- a/Tools/msi/crt/crt.wixproj +++ b/Tools/msi/crt/crt.wixproj @@ -10,7 +10,7 @@ - + diff --git a/Tools/msi/crt/crt_files.12.0.wxs b/Tools/msi/crt/crt_files.12.0.wxs deleted file mode 100644 index f62593faf4a..00000000000 --- a/Tools/msi/crt/crt_files.12.0.wxs +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - ALLUSERS=1 - - - - NOT ALLUSERS=1 - - - - - diff --git a/Tools/msi/crt/crt_files.14.0.wxs b/Tools/msi/crt/crt_files.14.0.wxs deleted file mode 100644 index be682c937bd..00000000000 --- a/Tools/msi/crt/crt_files.14.0.wxs +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - ALLUSERS=1 - - - - ALLUSERS=1 - - - - ALLUSERS=1 - - - - NOT ALLUSERS=1 - - - - NOT ALLUSERS=1 - - - - NOT ALLUSERS=1 - - - - - diff --git a/Tools/msi/crt/crt_files.wxs b/Tools/msi/crt/crt_files.wxs new file mode 100644 index 00000000000..46f7d6efc3c --- /dev/null +++ b/Tools/msi/crt/crt_files.wxs @@ -0,0 +1,20 @@ + + + + + + + + + + + ALLUSERS=1 + + + + NOT ALLUSERS=1 + + + + + diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 16839cc2522..cbaa6b14561 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -1,6 +1,7 @@ + $(OutputName) false false $(SuppressIces);ICE03;ICE57;ICE61 @@ -48,10 +49,8 @@ $(OutputPath)\ $(OutputPath) true - $(CommonProgramFiles)\Merge Modules\Microsoft_VC120_CRT_$(Platform).msm - $(CommonProgramFiles)\Merge Modules\Microsoft_VC140_CRT_$(Platform).msm - $([System.IO.Path]::GetFullPath(`$(VS120COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC120.CRT`)) - $([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`)) + $([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`)) + $(MSBuildThisFileDirectory)\redist\$(Platform) $(ReleaseLevelNumber) @@ -72,9 +71,6 @@ NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0; PyDebugExt=$(PyDebugExt); - - $(DefineConstants);CRTModule=$(CRTModule); - $(DefineConstants);CRTRedist=$(CRTRedist); @@ -115,6 +111,9 @@ crt + + redist + diff --git a/Tools/msi/redist/README.txt b/Tools/msi/redist/README.txt new file mode 100644 index 00000000000..48d26e1df0f --- /dev/null +++ b/Tools/msi/redist/README.txt @@ -0,0 +1,15 @@ +This folder is intentianally left empty in the repository. + +The following dependencies may be copied here if they cannot be detected +automatically by the build scripts: + +redist\Windows6.0-KB2999226-x64.msu +redist\Windows6.0-KB2999226-x86.msu +redist\Windows6.1-KB2999226-x64.msu +redist\Windows6.1-KB2999226-x86.msu +redist\Windows8.1-KB2999226-x64.msu +redist\Windows8.1-KB2999226-x86.msu +redist\Windows8-RT-KB2999226-x64.msu +redist\Windows8-RT-KB2999226-x86.msu +redist\x64\vcruntime140.dll +redist\x86\vcruntime140.dll