[Python-checkins] cpython: Updates CRT installation for Windows installer.

steve.dower python-checkins at python.org
Sun Mar 1 04:54:26 CET 2015


https://hg.python.org/cpython/rev/cfdba57d0070
changeset:   94792:cfdba57d0070
user:        Steve Dower <steve.dower at microsoft.com>
date:        Sat Feb 28 19:53:50 2015 -0800
summary:
  Updates CRT installation for Windows installer.
Bundling versions of the CRT prior to 14.0 is no longer supported.

files:
  Tools/msi/bundle/Default.wxl                                 |   5 +
  Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp |  88 +++++++++-
  Tools/msi/bundle/bundle.targets                              |   3 +
  Tools/msi/bundle/postinstall_en-US.wxl_template              |   3 +-
  Tools/msi/bundle/packagegroups/crt.wxs                       |  43 ++++
  Tools/msi/crt/crt.wixproj                                    |   2 +-
  Tools/msi/crt/crt_files.12.0.wxs                             |  20 --
  Tools/msi/crt/crt_files.14.0.wxs                             |  20 --
  Tools/msi/msi.props                                          |  13 +-
  Tools/msi/redist/README.txt                                  |  15 +
  10 files changed, 160 insertions(+), 52 deletions(-)


diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl
--- a/Tools/msi/bundle/Default.wxl
+++ b/Tools/msi/bundle/Default.wxl
@@ -11,6 +11,11 @@
   <String Id="Uninstalling">Removing</String>
   <String Id="Uninstallation">Uninstall</String>
   
+  <String Id="ElevateForCRTInstall">You will be prompted for Administrator privileges to install a C Runtime Library update (KB2999226).
+
+
+Continue?</String>
+  
   <String Id="CancelButton">&Cancel</String>
   <String Id="CloseButton">&Close</String>
   <String Id="InstallHeader">Install [WixBundleName]</String>
diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp
--- 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 @@
     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 @@
             ReleaseStr(targetDir);
             BalExitOnFailure(hr, "Failed to set install target directory");
 
+            if (!QueryElevateForCrtInstall()) {
+                break;
+            }
+
             OnPlan(BOOTSTRAPPER_ACTION_INSTALL);
             break;
 
@@ -352,6 +354,11 @@
                 ReleaseStr(targetDir);
             }
 
+            checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX);
+            if (!checked && !QueryElevateForCrtInstall()) {
+                break;
+            }
+
             OnPlan(_command.action);
             break;
 
@@ -2311,6 +2318,75 @@
         }
     }
 
+    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 @@
             }
         }
 
+        pEngine->SetVariableNumeric(L"CRTInstalled", IsCrtInstalled() ? 1 : 0);
+
         _wixLoc = nullptr;
         memset(&_bundle, 0, sizeof(_bundle));
         memset(&_conditions, 0, sizeof(_conditions));
@@ -2525,6 +2603,8 @@
         _suppressRepair = FALSE;
         _modifying = FALSE;
 
+        _crtInstalledToken = -1;
+
         _overridableVariables = nullptr;
         _taskbarList = nullptr;
         _taskbarButtonCreatedMessage = UINT_MAX;
@@ -2606,6 +2686,8 @@
     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
--- a/Tools/msi/bundle/bundle.targets
+++ b/Tools/msi/bundle/bundle.targets
@@ -10,6 +10,8 @@
         <OutputName Condition="!$(BuildForRelease)">$(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber)</OutputName>
         <OutputName Condition="$(Platform) == 'x64'">$(OutputName)-amd64</OutputName>
         <OutputName Condition="'$(OutputSuffix)' != ''">$(OutputName)-$(OutputSuffix)</OutputName>
+        <OutputName Condition="'$(Configuration)' == 'Debug'">$(OutputName)-d</OutputName>
+        <TargetName>$(OutputName)</TargetName>
 
         <OutputPath>$(OutputPath)en-us\</OutputPath>
         <OutDir>$(OutputPath)</OutDir>
@@ -43,6 +45,7 @@
         <Content Include="SideBar.png" />
     </ItemGroup>
     <ItemGroup>
+        <EmbeddedResource Include="bundle.wxl" />
         <WxlTemplate Include="*_en-US.wxl_template" />
     </ItemGroup>
     <ItemGroup>
diff --git a/Tools/msi/bundle/postinstall_en-US.wxl_template b/Tools/msi/bundle/bundle.wxl
rename from Tools/msi/bundle/postinstall_en-US.wxl_template
rename to Tools/msi/bundle/bundle.wxl
--- a/Tools/msi/bundle/postinstall_en-US.wxl_template
+++ b/Tools/msi/bundle/bundle.wxl
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
-    <String Id="CompileAllDescription">Precompiling standard library</String>
+  <String Id="CRTDescription">C Runtime Update (KB2999226)</String>
+  <String Id="CompileAllDescription">Precompiling standard library</String>
 </WixLocalization>
diff --git a/Tools/msi/bundle/packagegroups/crt.wxs b/Tools/msi/bundle/packagegroups/crt.wxs
--- a/Tools/msi/bundle/packagegroups/crt.wxs
+++ b/Tools/msi/bundle/packagegroups/crt.wxs
@@ -2,6 +2,11 @@
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
     <Fragment>
         <PackageGroup Id="crt">
+            <PackageGroupRef Id="crt_14.0_v6.0" />
+            <PackageGroupRef Id="crt_14.0_v6.1" />
+            <PackageGroupRef Id="crt_14.0_v6.2" />
+            <PackageGroupRef Id="crt_14.0_v6.3" />
+
             <MsiPackage Id="crt_AllUsers"
                         SourceFile="crt.msi"
                         Compressed="$(var.CompressMSI)"
@@ -22,4 +27,42 @@
             </MsiPackage>
         </PackageGroup>
     </Fragment>
+
+    <?foreach ver in v6.0;v6.1;v6.2;v6.3 ?>
+    <?if "$(var.ver)" = "v6.0" ?>
+    <?define msuver=6.0 ?>
+    <?elseif "$(var.ver)" = "v6.1" ?>
+    <?define msuver=6.1 ?>
+    <?elseif "$(var.ver)" = "v6.2" ?>
+    <?define msuver=8-RT ?>
+    <?elseif "$(var.ver)" = "v6.3" ?>
+    <?define msuver=8.1 ?>
+    <?else ?>
+    <?error unknown version $(var.ver) ?>
+    <?endif ?>
+
+    <Fragment>
+        <PackageGroup Id="crt_14.0_$(var.ver)">
+            <MsuPackage Id="crt_14.0_$(var.ver)_x86"
+                        KB="2999226"
+                        SourceFile="!(bindpath.redist)\Windows$(var.msuver)-KB2999226-x86.msu"
+                        DisplayName="!(loc.CRTDescription)"
+                        Description="!(loc.CRTDescription)"
+                        Compressed="$(var.CompressMSI)"
+                        DownloadUrl="$(var.DownloadUrl)"
+                        InstallCondition="not CRTInstalled and VersionNT = $(var.ver) and not VersionNT64 and (Include_core or Include_exe or Include_launcher or Include_pip)" />
+
+            <MsuPackage Id="crt_14.0_$(var.ver)_x64"
+                        KB="2999226"
+                        SourceFile="!(bindpath.redist)\Windows$(var.msuver)-KB2999226-x64.msu"
+                        DisplayName="!(loc.CRTDescription)"
+                        Description="!(loc.CRTDescription)"
+                        Compressed="$(var.CompressMSI)"
+                        DownloadUrl="$(var.DownloadUrl)"
+                        InstallCondition="not CRTInstalled and VersionNT64 = $(var.ver) and (Include_core or Include_exe or Include_launcher or Include_pip)" />
+        </PackageGroup>
+    </Fragment>
+
+    <?undef msuver ?>
+    <?endforeach ?>
 </Wix>
\ No newline at end of file
diff --git a/Tools/msi/crt/crt.wixproj b/Tools/msi/crt/crt.wixproj
--- a/Tools/msi/crt/crt.wixproj
+++ b/Tools/msi/crt/crt.wixproj
@@ -10,7 +10,7 @@
     <Import Project="..\msi.props" />
     <ItemGroup>
         <Compile Include="crt.wxs" />
-        <Compile Include="crt_files.$(VisualStudioVersion).wxs" />
+        <Compile Include="crt_files.wxs" />
     </ItemGroup>
     <ItemGroup>
         <EmbeddedResource Include="*.wxl" />
diff --git a/Tools/msi/crt/crt_files.12.0.wxs b/Tools/msi/crt/crt_files.12.0.wxs
deleted file mode 100644
--- a/Tools/msi/crt/crt_files.12.0.wxs
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-    <Fragment>
-        <?if $(var.Platform)~=x64 ?>
-        <?define msvcr120Guid={0835C947-D6D2-4E52-AF14-0231D04E88EA}?>
-        <?else ?>
-        <?define msvcr120Guid={E5B92048-5859-4AF1-AEAD-B97EBF00B087} ?>
-        <?endif ?>
-        <ComponentGroup Id="crt_files">
-            <Component Id="msvcr120.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.msvcr120Guid)" Shared="yes" SharedDllRefCount="yes">
-                <Condition>ALLUSERS=1</Condition>
-                <File Id="msvcr120.dll_LM" Source="!(bindpath.crt)\msvcr120.dll" />
-            </Component>
-            <Component Id="msvcr120.dll_CU" Directory="InstallDirectory" Guid="*">
-                <Condition>NOT ALLUSERS=1</Condition>
-                <File Id="msvcr120.dll_CU" Source="!(bindpath.crt)\msvcr120.dll" />
-            </Component>
-        </ComponentGroup>
-    </Fragment>
-</Wix>
diff --git a/Tools/msi/crt/crt_files.14.0.wxs b/Tools/msi/crt/crt_files.wxs
rename from Tools/msi/crt/crt_files.14.0.wxs
rename to Tools/msi/crt/crt_files.wxs
--- a/Tools/msi/crt/crt_files.14.0.wxs
+++ b/Tools/msi/crt/crt_files.wxs
@@ -2,35 +2,15 @@
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
     <Fragment>
         <?if $(var.Platform)~=x64 ?>
-        <?define appcrt140Guid={CC160FA9-B519-38EC-B358-B4146E8506C8}?>
-        <?define desktopcrt140Guid={4DB78A79-8D7F-35DD-B0E8-736DE44D25F3}?>
         <?define vcruntime140Guid={B33258FD-750C-3B42-8BE4-535B48E97DB4}?>
         <?else ?>
-        <?define appcrt140Guid={E3854F9C-4CFB-3B85-90BD-86AA22D82DC8}?>
-        <?define desktopcrt140Guid={46EAB1CD-C362-3139-BD7E-D8782E65253A}?>
         <?define vcruntime140Guid={E8E39D3B-4F35-36D8-B892-4B28336FE041}?>
         <?endif ?>
         <ComponentGroup Id="crt_files">
-            <Component Id="appcrt140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.appcrt140Guid)" Shared="yes" SharedDllRefCount="yes">
-                <Condition>ALLUSERS=1</Condition>
-                <File Id="appcrt140.dll_LM" Source="!(bindpath.crt)\appcrt140.dll" />
-            </Component>
-            <Component Id="desktopcrt140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.desktopcrt140Guid)" Shared="yes" SharedDllRefCount="yes">
-                <Condition>ALLUSERS=1</Condition>
-                <File Id="desktopcrt140.dll_LM" Source="!(bindpath.crt)\desktopcrt140.dll" />
-            </Component>
             <Component Id="vcruntime140.dll_LM" Directory="SystemInstallDirectory" Guid="$(var.vcruntime140Guid)" Shared="yes" SharedDllRefCount="yes">
                 <Condition>ALLUSERS=1</Condition>
                 <File Id="vcruntime140.dll_LM" Source="!(bindpath.crt)\vcruntime140.dll" />
             </Component>
-            <Component Id="appcrt140.dll_CU" Directory="InstallDirectory" Guid="*">
-                <Condition>NOT ALLUSERS=1</Condition>
-                <File Id="appcrt140.dll_CU" Source="!(bindpath.crt)\appcrt140.dll" />
-            </Component>
-            <Component Id="desktopcrt140.dll_CU" Directory="InstallDirectory" Guid="*">
-                <Condition>NOT ALLUSERS=1</Condition>
-                <File Id="desktopcrt140.dll_CU" Source="!(bindpath.crt)\desktopcrt140.dll" />
-            </Component>
             <Component Id="vcruntime140.dll_CU" Directory="InstallDirectory" Guid="*">
                 <Condition>NOT ALLUSERS=1</Condition>
                 <File Id="vcruntime140.dll_CU" Source="!(bindpath.crt)\vcruntime140.dll" />
diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props
--- a/Tools/msi/msi.props
+++ b/Tools/msi/msi.props
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="ReleaseUri">
     <PropertyGroup>
+        <TargetName>$(OutputName)</TargetName>
         <DefineSolutionProperties>false</DefineSolutionProperties>
         <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
         <SuppressIces>$(SuppressIces);ICE03;ICE57;ICE61</SuppressIces>
@@ -48,10 +49,8 @@
         <OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath>
         <OutDir>$(OutputPath)</OutDir>
         <ReuseCabinetCache>true</ReuseCabinetCache>
-        <CRTModule Condition="'$(VisualStudioVersion)' == '12.0'">$(CommonProgramFiles)\Merge Modules\Microsoft_VC120_CRT_$(Platform).msm</CRTModule>
-        <CRTModule Condition="'$(VisualStudioVersion)' == '14.0'">$(CommonProgramFiles)\Merge Modules\Microsoft_VC140_CRT_$(Platform).msm</CRTModule>
-        <CRTRedist Condition="'$(VisualStudioVersion)' == '12.0'">$([System.IO.Path]::GetFullPath(`$(VS120COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC120.CRT`))</CRTRedist>
-        <CRTRedist Condition="'$(VisualStudioVersion)' == '14.0'">$([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`))</CRTRedist>
+        <CRTRedist Condition="">$([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`))</CRTRedist>
+        <CRTRedist Condition="'$(CRTRedist)' != '' and !Exists($(CRTRedist))">$(MSBuildThisFileDirectory)\redist\$(Platform)</CRTRedist>
         <CRTRedist Condition="'$(CRTRedist)' != '' and !Exists($(CRTRedist))"></CRTRedist>
 
         <RevisionNumber>$(ReleaseLevelNumber)</RevisionNumber>
@@ -72,9 +71,6 @@
             NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0;
             PyDebugExt=$(PyDebugExt);
         </DefineConstants>
-        <DefineConstants Condition="'$(CRTModule)' != '' and Exists($(CRTModule))">
-            $(DefineConstants);CRTModule=$(CRTModule);
-        </DefineConstants>
         <DefineConstants Condition="'$(CRTRedist)' != ''">
             $(DefineConstants);CRTRedist=$(CRTRedist);
         </DefineConstants>
@@ -115,6 +111,9 @@
         <LinkerBindInputPaths Include="$(CRTRedist)" Condition="'$(CRTRedist)' != ''">
             <BindName>crt</BindName>
         </LinkerBindInputPaths>
+        <LinkerBindInputPaths Include="$(MSBuildThisFileDirectory)\redist">
+            <BindName>redist</BindName>
+        </LinkerBindInputPaths>
     </ItemGroup>
 
     <Target Name="_ValidateMsiProps" BeforeTargets="PrepareForBuild">
diff --git a/Tools/msi/redist/README.txt b/Tools/msi/redist/README.txt
new file mode 100644
--- /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

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list