Refresh windows docker setup
diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml
new file mode 100644
index 0000000..deb08c3
--- /dev/null
+++ b/.github/workflows/msvc.yml
@@ -0,0 +1,129 @@
+name: MSVC Build 
+
+on:
+  push:
+    branches: [ '*' ]
+  pull_request:
+    branches: [ '*' ]
+
+permissions:
+  contents: read
+  packages: write
+
+jobs:
+  build:
+    runs-on: windows-2022
+    env:
+      THRIFT_BUILD_DIR: C:\thrift-build
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Ensure expected workspace path
+        shell: pwsh
+        run: |
+          if (-not (Test-Path 'C:\src')) { New-Item -Path 'C:\src' -ItemType Directory | Out-Null }
+          if (Test-Path 'C:\src\thrift') { Remove-Item 'C:\src\thrift' -Recurse -Force }
+          cmd /c mklink /J C:\src\thrift $env:GITHUB_WORKSPACE
+
+      - name: Configure build output directory
+        shell: pwsh
+        run: |
+          New-Item -Path $env:THRIFT_BUILD_DIR -ItemType Directory -Force | Out-Null
+
+      - name: Set Docker image name
+        shell: pwsh
+        env:
+          OWNER: ${{ github.repository_owner }}
+        run: |
+          $image = "ghcr.io/{0}/thrift-build" -f $env:OWNER.ToLower()
+          "DOCKER_IMAGE=$image" | Out-File -FilePath $env:GITHUB_ENV -Append
+
+      - name: Compute Docker image tag
+        shell: pwsh
+        run: |
+          $hash = (Get-FileHash -Algorithm SHA256 'build/docker/msvc2017/Dockerfile').Hash.ToLower().Substring(0, 12)
+          "IMAGE_TAG=msvc2017-$hash" | Out-File -FilePath $env:GITHUB_ENV -Append
+
+      - name: Log in to GHCR
+        uses: docker/login-action@v3
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Pull cached image
+        id: pull_cached
+        continue-on-error: true
+        shell: pwsh
+        run: |
+          $needBuild = $true
+
+          Write-Host "Attempting to pull hash-based tag: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)"
+          docker pull "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" 2>&1 | Out-Host
+          if ($LASTEXITCODE -eq 0) {
+            Write-Host "Successfully pulled cached image with hash tag"
+            $needBuild = $false
+          } else {
+            Write-Host "Hash tag not found, no fallback configured. Will build from scratch."
+            $needBuild = $true
+          }
+
+          Write-Host "Setting outputs: need_build=$needBuild"
+          "need_build=$needBuild" >> $env:GITHUB_OUTPUT
+
+      - name: Build Docker image
+        if: steps.pull_cached.outputs.need_build == 'true'
+        shell: pwsh
+        run: |
+          Write-Host "Building with tag: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)"
+          docker build -t "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" -f build\docker\msvc2017\Dockerfile 'build\'
+          if ($LASTEXITCODE -ne 0) {
+            Write-Error "Docker build failed"
+            exit 1
+          }
+          Write-Host "Verifying tags were created:"
+          docker images "$($env:DOCKER_IMAGE)"
+
+      - name: Push Docker image
+        if: github.event_name != 'pull_request' && steps.pull_cached.outputs.need_build == 'true'
+        shell: pwsh
+        run: |
+          Write-Host "Pushing hash-based tag only: $($env:DOCKER_IMAGE):$($env:IMAGE_TAG)"
+          docker push "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)"
+          if ($LASTEXITCODE -ne 0) {
+            Write-Error "Failed to push hash-based tag"
+            exit 1
+          }
+          Write-Host "Successfully pushed hash-tagged image"
+
+      - name: Build and test inside container
+        shell: pwsh
+        run: |
+          docker run -v c:\src\thrift:C:\Thrift -v "${env:THRIFT_BUILD_DIR}:C:\build" --rm -t "$($env:DOCKER_IMAGE):$($env:IMAGE_TAG)" c:\thrift\build\docker\msvc2017\build.bat
+
+      - name: Check test results
+        if: always()
+        shell: pwsh
+        run: |
+          $logPath = Join-Path $env:THRIFT_BUILD_DIR 'Testing\Temporary\LastTest.log'
+          if (Test-Path $logPath) {
+            $content = Get-Content $logPath -Raw
+            if ($content -match 'Test Failed\.') {
+              Write-Error "Tests failed - check LastTest.log artifact for details"
+              exit 1
+            } else {
+              Write-Host "All tests passed"
+            }
+          } else {
+            Write-Warning "LastTest.log not found at $logPath"
+          }
+
+      - name: Upload LastTest log
+        if: always()
+        uses: actions/upload-artifact@v4
+        with:
+          name: msvc2017-LastTest-log
+          path: ${{ env.THRIFT_BUILD_DIR }}\Testing\Temporary\LastTest.log
+          if-no-files-found: warn
diff --git a/build/docker/msvc2017/Dockerfile b/build/docker/msvc2017/Dockerfile
index a29753e..4502a59 100644
--- a/build/docker/msvc2017/Dockerfile
+++ b/build/docker/msvc2017/Dockerfile
@@ -13,38 +13,38 @@
 # limitations under the License.
 #
 
-FROM microsoft/dotnet-framework:4.7.1
+FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2022
 
 # Restore the default Windows shell for correct batch processing below.
 SHELL ["cmd", "/S", "/C"]
 
 # Install Build Tools excluding workloads and components with known issues.
-ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
+ADD --checksum=sha256:ca11782db44225d313c9887b4254dfa57c5b72fef025bf620c81c43dff73c6ed https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
 RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
     --installPath C:\BuildTools `
-    --all `
-    --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
-    --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
-    --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
-    --remove Microsoft.VisualStudio.Component.Windows81SDK `
+    --add Microsoft.VisualStudio.Workload.VCTools `
+    --add Microsoft.VisualStudio.Component.Windows10SDK.19041 `
  || IF "%ERRORLEVEL%"=="3010" EXIT 0
 RUN DEL C:\TEMP\vs_buildtools.exe
 
 # Install CMake
-ADD https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi C:\TEMP\cmake.msi
+ADD --checksum=sha256:a10fc2527ec0727a5913acd310cddafba1e5b4ca765ca23cc6a53c55eebb7c1 https://github.com/Kitware/CMake/releases/download/v4.1.2/cmake-4.1.2-windows-x86_64.msi C:\TEMP\cmake.msi
 RUN msiexec.exe /i C:\TEMP\cmake.msi /qn && `
     SETX PATH "%PATH%;C:\Program Files\CMake\bin" && `
     DEL C:\TEMP\cmake.msi
 
 # Install boost (for the thrift runtime library build)
-ADD https://boost.teeks99.com/bin/1.69.0/boost_1_69_0-msvc-14.1-64.exe C:\TEMP\boost.exe
-RUN C:\TEMP\boost.exe /DIR="C:\Libraries\boost_1_69_0" /SILENT && `
-    DEL C:\TEMP\boost.exe
+ADD --checksum=sha256:ae6ade62886fd9a6930c95f116a33e940224f0cb7f791b01afd7dd1ceca360fe https://boost.teeks99.com/bin/1.88.0/boost_1_88_0-msvc-14.1-64.exe C:\TEMP\boost.exe
+ENV BOOST_ROOT=C:\Libraries\boost_1_88_0
+RUN C:\TEMP\boost.exe /DIR=%BOOST_ROOT% /SILENT && `
+    DEL C:\TEMP\boost.exe && `
+    SETX BOOST_LIBRARYDIR "%BOOST_ROOT%\lib64-msvc-14.1" && `
+    SETX PATH "%BOOST_LIBRARYDIR%;%PATH%"
 
 # Install chocolatey
 RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" `
     -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command `
-    "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" `
+    "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" `
     && SETX PATH "%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
 
 # Install winflexbison (for the thrift compiler build)
@@ -57,44 +57,52 @@
 COPY appveyor\build-libevent.bat C:\TEMP\build-libevent.bat
 ENV LIBEVENT_VERSION=2.1.8
 ENV WIN3P=C:\TEMP\WIN3P
-RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && `
+RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && `
     MKDIR C:\TEMP\WIN3P && `
     C:\TEMP\build-libevent.bat && `
     MKDIR C:\Libraries\libevent-%LIBEVENT_VERSION% && `
     MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\include C:\Libraries\libevent-%LIBEVENT_VERSION% && `
     MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\lib C:\Libraries\libevent-%LIBEVENT_VERSION% && `
-    RMDIR /S /Q C:\TEMP\WIN3P
+    RMDIR /S /Q C:\TEMP\WIN3P && `
+    SETX LIBEVENT_ROOT "C:\Libraries\libevent-%LIBEVENT_VERSION%"
 
 # Install zlib
 COPY appveyor\build-zlib.bat C:\TEMP\build-zlib.bat
-ENV ZLIB_VERSION=1.2.13
+ENV ZLIB_VERSION=1.3.1
 ENV WIN3P=C:\TEMP\WIN3P
-RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && `
+RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 && `
     MKDIR C:\TEMP\WIN3P && `
     C:\TEMP\build-zlib.bat && `
     MOVE C:\TEMP\WIN3P\zlib-inst C:\Libraries\zlib-%ZLIB_VERSION% && `
-    RMDIR /S /Q C:\TEMP\WIN3P
+    RMDIR /S /Q C:\TEMP\WIN3P && `
+    SETX ZLIB_ROOT "C:\Libraries\zlib-%ZLIB_VERSION%" && `
+    SETX PATH "%ZLIB_ROOT%\bin;%PATH%"
 
-# Install OpenSSL 1.1.0
-ADD http://slproweb.com/download/Win64OpenSSL-1_1_0l.exe C:\TEMP\openssl.exe
+# Install OpenSSL 3.6.0
+ADD --checksum=sha256:1ae24eb941ff3c11258d0ad4e6d2cba13360cb52a17d8516fb27352b5e3ed6ad https://slproweb.com/download/Win64OpenSSL-3_6_0.exe C:\TEMP\openssl.exe
 RUN C:\TEMP\openssl.exe /silent && `
-    DEL C:\TEMP\openssl.exe
+    DEL C:\TEMP\openssl.exe && `
+    SETX OPENSSL_ROOT "C:\OpenSSL-Win64" && `
+    SETX PATH "%OPENSSL_ROOT%\bin;%PATH%"
 
 # Install java
 RUN choco install jdk8 -y
 
 # Install python3
 RUN choco install python3 -y
+RUN pip install setuptools
 
 # Install Adobe Flex 4.6 SDK and set FLEX_HOME so it can be found
-ADD http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip
+ADD --checksum=sha256:622b63f29de44600ff8d4231174a70fcb3085812c0e146a42e91877ca8b46798 http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip
 RUN CD C:\Adobe\Flex\SDK\4.6 && `
     7z x SDK.zip && `
     DEL SDK.zip && `
     SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6"
 
+RUN choco install nodejs -y
+
 # Start developer command prompt with any other commands specified.
-ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 &&
+ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=x64 -host_arch=x64 &&
 
 # Default to PowerShell if no other command specified.
-CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
+CMD powershell.exe -NoLogo -ExecutionPolicy Bypass
diff --git a/build/docker/msvc2017/build-compiler.bat b/build/docker/msvc2017/build-compiler.bat
index a7ed479..a870af8 100644
--- a/build/docker/msvc2017/build-compiler.bat
+++ b/build/docker/msvc2017/build-compiler.bat
@@ -26,8 +26,8 @@
 
 :: Generate the out-of-tree build files
 cmake^
-  -DBOOST_ROOT=C:\Libraries\boost_1_69_0^
-  -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^
+  -DBOOST_ROOT=C:\Libraries\boost_1_89_0^
+  -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_89_0\lib64-msvc-14.1^
   -DBUILD_LIBRARIES=OFF^
   -DCMAKE_BUILD_TYPE=Release^
   -DCMAKE_INSTALL_PREFIX=C:\install^
@@ -38,7 +38,7 @@
 cmake --build . --target thrift-compiler --config Release || EXIT /B
 
 :: Test
-cmake --build . --target check || EXIT /B
+ctest -C Release || EXIT /B
 
 :: Install
 cmake --install .
\ No newline at end of file
diff --git a/build/docker/msvc2017/build.bat b/build/docker/msvc2017/build.bat
index bdf1512..a07160b 100644
--- a/build/docker/msvc2017/build.bat
+++ b/build/docker/msvc2017/build.bat
@@ -26,12 +26,13 @@
 
 :: Generate the out-of-tree build files
 cmake^
-  -DBOOST_ROOT=C:\Libraries\boost_1_69_0^
-  -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^
-  -DFLEX_HOME=C:\Adobe\Flex\SDK\4.6^
-  -DLIBEVENT_ROOT=C:\Libraries\libevent-2.1.8^
-  -DZLIB_ROOT=C:\Libraries\zlib-1.2.11^
+  -DCMAKE_GENERATOR_PLATFORM=x64^
+  -DBOOST_ROOT=%BOOST_ROOT%^
+  -DFLEX_HOME=%FLEX_HOME%^
+  -DLIBEVENT_ROOT=%LIBEVENT_ROOT%^
+  -DZLIB_ROOT=%ZLIB_ROOT%^
   -DCMAKE_BUILD_TYPE=Release^
+  -DBUILD_SHARED_LIBS=OFF^
   -DCMAKE_INSTALL_PREFIX=C:\install^
   c:\thrift || EXIT /B
 
@@ -39,7 +40,7 @@
 cmake --build . --config Release || EXIT /B
 
 :: Test
-cmake --build . --target check || EXIT /B
+ctest -C Release || EXIT /B
 
 :: Install
 cmake --install .