diff --git a/.azure-pipelines/scripts/install-vs-cpp-workload.ps1 b/.azure-pipelines/scripts/install-vs-cpp-workload.ps1
index 9e8e77f99..0a4502042 100644
--- a/.azure-pipelines/scripts/install-vs-cpp-workload.ps1
+++ b/.azure-pipelines/scripts/install-vs-cpp-workload.ps1
@@ -1,20 +1,20 @@
#
-# Ensure a Visual Studio 2022 (or newer) install with the "Desktop
+# Ensure a Visual Studio 2026 (or newer) install with the "Desktop
# development with C++" workload is present on the build agent.
#
# .NET NativeAOT publishing (used by every product-facing managed VFS for
# Git project via PublishAot=true in Directory.Build.props) requires the
# C++ build tools from this workload at publish time. The native VFS
-# projects also build against the v143 toolset, which ships with VS 2022.
+# projects also build against the v145 toolset, which ships with VS 2026.
#
# This script handles three situations:
-# 1. A VS 2022+ install with the C++ workload is already present
+# 1. A VS 2026+ install with the C++ workload is already present
# -> exit early.
-# 2. A VS 2022+ install (any product) is present but the C++ workload
+# 2. A VS 2026+ install (any product) is present but the C++ workload
# is missing -> modify that install to add it.
-# 3. No VS 2022+ install at all -> install VS Build Tools 2022 with
-# the VC tools workload. (An older VS install, e.g. VS 2019, is
-# ignored here -- we leave it alone and install VS 2022 alongside.)
+# 3. No VS 2026+ install at all -> install VS Build Tools 2026 with
+# the VC tools workload. (An older VS install, e.g. VS 2022, is
+# ignored here -- we leave it alone and install VS 2026 alongside.)
#
# vswhere.exe is bootstrapped from GitHub if not already on disk.
#
@@ -39,12 +39,12 @@ $vswherePath = Join-Path $vsInstallerDir 'vswhere.exe'
$setupExePath = Join-Path $vsInstallerDir 'setup.exe'
$vswhereDownloadUrl = 'https://github.com/microsoft/vswhere/releases/latest/download/vswhere.exe'
-$buildToolsDownloadUrl = 'https://aka.ms/vs/17/release/vs_BuildTools.exe'
+$buildToolsDownloadUrl = 'https://aka.ms/vs/18/release/vs_BuildTools.exe'
-# The native VFS projects build against the v143 toolset, which ships with
-# Visual Studio 2022 (product line 17.x). VS 2019 (16.x) carries v142 and
-# is not sufficient -- so all vswhere queries below are scoped to 17.0+.
-$minVsVersion = '[17.0,)'
+# The native VFS projects build against the v145 toolset, which ships with
+# Visual Studio 2026 (product line 18.x). VS 2022 (17.x) carries v143 and
+# is not sufficient -- so all vswhere queries below are scoped to 18.0+.
+$minVsVersion = '[18.0,)'
# Either of these workloads provides the C++ build tools we need.
# Microsoft.VisualStudio.Workload.NativeDesktop = "Desktop development with C++" (Community/Pro/Enterprise).
@@ -132,9 +132,9 @@ if ($existing) {
# --- Find any VS install (regardless of workloads) ---
$install = Find-VsInstall -VswhereExe $vswhereExe
-# --- If no VS 2022+ install at all, install VS Build Tools 2022 with the VC workload ---
+# --- If no VS 2026+ install at all, install VS Build Tools 2026 with the VC workload ---
if (-not $install) {
- Write-Host "No Visual Studio 2022 (or newer) installation found; installing VS Build Tools 2022 with the C++ workload..."
+ Write-Host "No Visual Studio 2026 (or newer) installation found; installing VS Build Tools 2026 with the C++ workload..."
$bootstrapper = Join-Path $env:TEMP 'vs_BuildTools.exe'
Write-Host "Downloading VS Build Tools bootstrapper from $buildToolsDownloadUrl..."
Invoke-WebRequest -Uri $buildToolsDownloadUrl -OutFile $bootstrapper -UseBasicParsing
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index d0b4a4509..49cb472e3 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -255,7 +255,12 @@ jobs:
path: MicrosoftGit
build:
- runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-arm' || 'windows-2025' }}
+ # arm64 uses the preview 'windows-11-vs2026-arm' image because the native
+ # C++ projects target the v145 toolset (VS 2026). The default
+ # 'windows-11-arm' image still ships VS 2022 (v145 absent); it migrates to
+ # VS 2026 in early September 2026, after which this can revert to
+ # 'windows-11-arm'. x64 'windows-2025' already ships VS 2026.
+ runs-on: ${{ matrix.architecture == 'arm64' && 'windows-11-vs2026-arm' || 'windows-2025' }}
name: Build and Unit Test
needs: validate
@@ -290,6 +295,11 @@ jobs:
- name: Add MSBuild to PATH
if: steps.skip.outputs.result != 'true'
uses: microsoft/setup-msbuild@v3.0.0
+ with:
+ # Pin to Visual Studio 2026 (18.0+). Runner images that still carry
+ # VS 2022 alongside VS 2026 would otherwise put the 2022 MSBuild on
+ # PATH, and the native projects (v145 toolset) fail with MSB8020.
+ vs-version: '[18.0,)'
- name: Build VFS for Git
if: steps.skip.outputs.result != 'true'
diff --git a/.vsconfig b/.vsconfig
index 095606afa..05d718a16 100644
--- a/.vsconfig
+++ b/.vsconfig
@@ -5,7 +5,7 @@
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.1.SDK",
"Microsoft.Net.Core.Component.SDK.8.0",
- "Microsoft.VisualStudio.Component.VC.v143.x86.x64",
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows11SDK.26100",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
diff --git a/GVFS/GVFS.NativeTests/GVFS.NativeTests.vcxproj b/GVFS/GVFS.NativeTests/GVFS.NativeTests.vcxproj
index 041163bea..11aa6a7d3 100644
--- a/GVFS/GVFS.NativeTests/GVFS.NativeTests.vcxproj
+++ b/GVFS/GVFS.NativeTests/GVFS.NativeTests.vcxproj
@@ -31,14 +31,14 @@
DynamicLibrary
true
NotSet
- v143
+ v145
DynamicLibrary
false
true
NotSet
- v143
+ v145
diff --git a/GVFS/GVFS.PostIndexChangedHook/GVFS.PostIndexChangedHook.vcxproj b/GVFS/GVFS.PostIndexChangedHook/GVFS.PostIndexChangedHook.vcxproj
index 8e8f32a5f..4150e9056 100644
--- a/GVFS/GVFS.PostIndexChangedHook/GVFS.PostIndexChangedHook.vcxproj
+++ b/GVFS/GVFS.PostIndexChangedHook/GVFS.PostIndexChangedHook.vcxproj
@@ -31,14 +31,14 @@
Application
true
MultiByte
- v143
+ v145
Application
false
true
MultiByte
- v143
+ v145
diff --git a/GVFS/GVFS.ReadObjectHook/GVFS.ReadObjectHook.vcxproj b/GVFS/GVFS.ReadObjectHook/GVFS.ReadObjectHook.vcxproj
index cd6ccc65e..6ce96a44c 100644
--- a/GVFS/GVFS.ReadObjectHook/GVFS.ReadObjectHook.vcxproj
+++ b/GVFS/GVFS.ReadObjectHook/GVFS.ReadObjectHook.vcxproj
@@ -31,14 +31,14 @@
Application
true
MultiByte
- v143
+ v145
Application
false
true
MultiByte
- v143
+ v145
diff --git a/GVFS/GVFS.VirtualFileSystemHook/GVFS.VirtualFileSystemHook.vcxproj b/GVFS/GVFS.VirtualFileSystemHook/GVFS.VirtualFileSystemHook.vcxproj
index 026b18af4..703ddd7a8 100644
--- a/GVFS/GVFS.VirtualFileSystemHook/GVFS.VirtualFileSystemHook.vcxproj
+++ b/GVFS/GVFS.VirtualFileSystemHook/GVFS.VirtualFileSystemHook.vcxproj
@@ -31,14 +31,14 @@
Application
true
MultiByte
- v143
+ v145
Application
false
true
MultiByte
- v143
+ v145
diff --git a/GVFS/GitHooksLoader/GitHooksLoader.vcxproj b/GVFS/GitHooksLoader/GitHooksLoader.vcxproj
index 28513e8ef..a99300ca6 100644
--- a/GVFS/GitHooksLoader/GitHooksLoader.vcxproj
+++ b/GVFS/GitHooksLoader/GitHooksLoader.vcxproj
@@ -29,14 +29,14 @@
Application
true
Unicode
- v143
+ v145
Application
false
true
Unicode
- v143
+ v145
diff --git a/Readme.md b/Readme.md
index c72ae98d5..1927110ce 100644
--- a/Readme.md
+++ b/Readme.md
@@ -35,7 +35,7 @@ will notify you when new versions are available.
## Building VFS for Git
If you'd like to build your own VFS for Git Windows installer:
-* Install Visual Studio 2022 Community Edition or higher (https://www.visualstudio.com/downloads/).
+* Install Visual Studio 2026 Community Edition or higher (https://www.visualstudio.com/downloads/).
* Include the following workloads:
* .NET desktop development
* Desktop development with C++
@@ -50,7 +50,7 @@ If you'd like to build your own VFS for Git Windows installer:
build will fail, and the second and subsequent builds will succeed. This is because the build requires a prebuild code generation step.
For details, see the build script in the previous step.
-Visual Studio 2022 will [automatically prompt you to install these dependencies](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/) when you open the solution. The .vsconfig file that is present in the root of the repository specifies all required components.
+Visual Studio 2026 will [automatically prompt you to install these dependencies](https://devblogs.microsoft.com/setup/configure-visual-studio-across-your-organization-with-vsconfig/) when you open the solution. The .vsconfig file that is present in the root of the repository specifies all required components.
The installer can now be found at `C:\Repos\VFSForGit\out\GVFS.Installers\bin\[Debug|Release]\win-x64\SetupGVFS..exe`
diff --git a/scripts/Build.bat b/scripts/Build.bat
index 592020f59..fffa7ae7e 100644
--- a/scripts/Build.bat
+++ b/scripts/Build.bat
@@ -48,7 +48,7 @@ REM emits the literal vswhere "not recognized" stderr into the link command
REM line and the publish step fails with a malformed link.rsp invocation.
SET "PATH=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer;%PATH%"
-REM .NET 10 SDK ships MSBuild 18.x; VS 2022 ships MSBuild 17.x.
+REM .NET 10 SDK ships MSBuild 18.x; VS 2026 ships MSBuild 18.x.
REM Managed (csproj) projects require MSBuild 18.x via "dotnet build".
REM Native C++ (vcxproj) projects require VS MSBuild with VC++ targets.
@@ -101,28 +101,33 @@ ECHO INFO: Using vcpkg at '%VCPKG_EXEC%'
ECHO ^**************************
ECHO ^* Building C++ Projects *
ECHO ^**************************
-REM Locate VS MSBuild for native C++ projects
+REM Locate VS MSBuild for the native C++ projects. Prefer the newest Visual
+REM Studio via "vswhere -latest" so MSBuild resolves the v145 toolset the
+REM vcxproj files target (VS 2026). A build agent may also carry VS 2022
+REM (v170 / v143); a bare "where msbuild.exe" can return that older MSBuild,
+REM which then fails with MSB8020 (v145 build tools not found). "-latest"
+REM sorts installs by version and returns the newest (18.x before 17.x), so
+REM query vswhere first and only fall back to PATH when vswhere is unavailable.
SET MSBUILD_EXEC=
-FOR /F "tokens=* USEBACKQ" %%F IN (`where msbuild.exe 2^>nul`) DO (
- SET MSBUILD_EXEC=%%F
- ECHO INFO: Found msbuild.exe at '%%F'
- GOTO :FOUND_MSBUILD
-)
-
-:LOCATE_MSBUILD
SET VSWHERE_EXEC="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
IF EXIST %VSWHERE_EXEC% (
- FOR /F "tokens=* USEBACKQ" %%F IN (`%VSWHERE_EXEC% -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find MSBuild\**\Bin\amd64\MSBuild.exe`) DO (
- SET MSBUILD_EXEC=%%F
- ECHO INFO: Found msbuild.exe at '%%F'
+ FOR /F "tokens=* USEBACKQ" %%F IN (`%VSWHERE_EXEC% -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find MSBuild\**\Bin\MSBuild.exe`) DO (
+ SET "MSBUILD_EXEC=%%F"
+ )
+)
+IF NOT DEFINED MSBUILD_EXEC (
+ FOR /F "tokens=* USEBACKQ" %%F IN (`where msbuild.exe 2^>nul`) DO (
+ SET "MSBUILD_EXEC=%%F"
+ GOTO :FOUND_MSBUILD
)
)
:FOUND_MSBUILD
IF NOT DEFINED MSBUILD_EXEC (
- ECHO ERROR: Could not find VS MSBuild. Install Visual Studio with the C++ workload to build native projects.
+ ECHO ERROR: Could not find Visual Studio 2026 MSBuild. Install Visual Studio 2026 with the C++ workload to build native projects.
EXIT /B 1
)
+ECHO INFO: Using msbuild.exe at '%MSBUILD_EXEC%'
REM Initialize the VC++ developer environment for the target architecture so
REM MSBuild can locate the matching cl.exe / link.exe and the right INCLUDE/LIB
@@ -136,11 +141,20 @@ IF EXIST %VSWHERE_VC% (
)
)
IF NOT DEFINED VCVARS_BAT (
- ECHO ERROR: Could not find vcvarsall.bat. Install Visual Studio with the C++ workload.
+ ECHO ERROR: Could not find Visual Studio 2026 vcvarsall.bat. Install Visual Studio 2026 with the C++ workload.
EXIT /B 1
)
-ECHO INFO: Initializing VC++ env for %ARCH% via "%VCVARS_BAT%"
-CALL "%VCVARS_BAT%" %ARCH% || GOTO ERROR
+REM Select the vcvars host_target argument. For arm64 targets, use the
+REM x64-hosted arm64 cross toolset (amd64_arm64) rather than the native arm64
+REM toolset (plain "arm64"). The VS 2026 native arm64 compiler fails to build
+REM GVFS.NativeTests with C3859 / C1076 (PCH virtual-memory / internal heap
+REM limit) -- a known ARM64-native-compiler limitation. The x64-hosted cross
+REM compiler (which VS uses by default for arm64) has the address space to
+REM build the PCH and produces equivalent arm64 binaries.
+SET "VCVARS_ARG=%ARCH%"
+IF "%ARCH%"=="arm64" SET "VCVARS_ARG=amd64_arm64"
+ECHO INFO: Initializing VC++ env (%VCVARS_ARG%) for %ARCH% via "%VCVARS_BAT%"
+CALL "%VCVARS_BAT%" %VCVARS_ARG% || GOTO ERROR
FOR %%P IN (
"%VFS_SRCDIR%\GVFS\GitHooksLoader\GitHooksLoader.vcxproj"