From bff1870fbc98106201dc2bf48c652e1518d2e88d Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 4 Nov 2025 10:47:01 -0800 Subject: [PATCH 01/13] Enable preview SDK in Test run this is on .cmd because the claim is the release version of vs 2022 doesn't allow preview sdks. the global.json should also be able to enable preview sdks but many tests use a custom global.json file. Whether this will actually resolve correctly, I don't know. But if the only problem was that it could resolve before but now skips preview sdks, then this could work. --- build/RunTestsOnHelix.cmd | 1 + 1 file changed, 1 insertion(+) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index f55fcf1ead42..dedfcc4d3436 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -5,6 +5,7 @@ set NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT=6 set NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 set MicrosoftNETBuildExtensionsTargets=%HELIX_CORRELATION_PAYLOAD%\ex\msbuildExtensions\Microsoft\Microsoft.NET.Build.Extensions\Microsoft.NET.Build.Extensions.targets +set DOTNET_CLI_ALLOW_PREVIEW_SDK=1 set DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\d set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 From 5725c746a1d1b54053f30c2bdbceb09edc17a174 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 4 Nov 2025 11:08:11 -0800 Subject: [PATCH 02/13] Set the Resolver CLI Dir I thought that MSBuildSDKsPath would work because of the error being propagated: the line of code which uses the default sdk resolver does look at msbuildsdkspath https://github.com/dotnet/msbuild/blob/27c7c81bbd20f7bf1252782826c1fc8ee1427b2f/src/Build/BackEnd/Components/SdkResolution/DefaultSdkResolver.cs#L33 to https://github.com/dotnet/msbuild/blob/27c7c81bbd20f7bf1252782826c1fc8ee1427b2f/src/Shared/BuildEnvironmentHelper.cs#L670, but I think that points to the MSBuild SDKs (the Sdk/ content under a selected SDK), but does not control which SDK version is selected /r is supposedly the sdks resolver path, but maybe we actually want /d since it's the hostfxr path we're really giving --- build/RunTestsOnHelix.cmd | 1 + 1 file changed, 1 insertion(+) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index dedfcc4d3436..a94e1e02c7ea 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -7,6 +7,7 @@ set NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 set MicrosoftNETBuildExtensionsTargets=%HELIX_CORRELATION_PAYLOAD%\ex\msbuildExtensions\Microsoft\Microsoft.NET.Build.Extensions\Microsoft.NET.Build.Extensions.targets set DOTNET_CLI_ALLOW_PREVIEW_SDK=1 set DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\d +set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\r set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 From 40ba94abcd402fca0a6844131ce16ed0e61c094e Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 4 Nov 2025 14:05:22 -0800 Subject: [PATCH 03/13] Use \d as it represents the host location, while \r represents the msbuild sdks location I'm not sure if the property even worked, because the error code is the same and the code doesn't seem to point to using this cli_dir. will try msbuildsdks property mentioned earlier next. --- build/RunTestsOnHelix.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index a94e1e02c7ea..8f5f2605c3c6 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -7,7 +7,7 @@ set NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 set MicrosoftNETBuildExtensionsTargets=%HELIX_CORRELATION_PAYLOAD%\ex\msbuildExtensions\Microsoft\Microsoft.NET.Build.Extensions\Microsoft.NET.Build.Extensions.targets set DOTNET_CLI_ALLOW_PREVIEW_SDK=1 set DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\d -set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\r +set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\d set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 From 97693171c5869f9a0af7c08eae1b3cb78645c897 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 4 Nov 2025 14:13:33 -0800 Subject: [PATCH 04/13] remove possible ai nonsense --- build/RunTestsOnHelix.cmd | 1 - 1 file changed, 1 deletion(-) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index 8f5f2605c3c6..eecd11ef4382 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -5,7 +5,6 @@ set NUGET_EXPERIMENTAL_MAX_NETWORK_TRY_COUNT=6 set NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 set MicrosoftNETBuildExtensionsTargets=%HELIX_CORRELATION_PAYLOAD%\ex\msbuildExtensions\Microsoft\Microsoft.NET.Build.Extensions\Microsoft.NET.Build.Extensions.targets -set DOTNET_CLI_ALLOW_PREVIEW_SDK=1 set DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\d set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\d set PATH=%DOTNET_ROOT%;%PATH% From c477e2aa205cf9039407edd7e1b8c1116c12ed61 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 5 Nov 2025 10:00:26 -0800 Subject: [PATCH 05/13] try to enable preview sdks on build credit to roslyn repo for this idea --- eng/common/tools.ps1 | 20 ++++++++++++++++++-- eng/restore-toolset.ps1 | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 9b3ad8840fdb..0123624a0a90 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -295,7 +295,7 @@ function InstallDotNet([string] $dotnetRoot, if ($runtime -eq "aspnetcore") { $runtimePath = $runtimePath + "\Microsoft.AspNetCore.App" } if ($runtime -eq "windowsdesktop") { $runtimePath = $runtimePath + "\Microsoft.WindowsDesktop.App" } $runtimePath = $runtimePath + "\" + $version - + $dotnetVersionLabel = "runtime toolset '$runtime/$architecture v$version'" if (Test-Path $runtimePath) { @@ -576,6 +576,22 @@ function LocateVisualStudio([object]$vsRequirements = $null){ return $vsInfo[0] } +function EnablePreviewSdks() { + $vsInfo = LocateVisualStudio + if ($vsInfo -eq $null) { + # Preview SDKs are allowed when no Visual Studio instance is installed + return + } + + $vsId = $vsInfo.instanceId + $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] + + $instanceDir = Join-Path ${env:USERPROFILE} "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsId" + Create-Directory $instanceDir + $sdkFile = Join-Path $instanceDir "sdk.txt" + 'UsePreviews=True' | Set-Content $sdkFile +} + function InitializeBuildTool() { if (Test-Path variable:global:_BuildTool) { # If the requested msbuild parameters do not match, clear the cached variables. @@ -610,7 +626,7 @@ function InitializeBuildTool() { } else { $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework } - + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework } } elseif ($msbuildEngine -eq "vs") { try { diff --git a/eng/restore-toolset.ps1 b/eng/restore-toolset.ps1 index 83b1fbea151e..2aece3129a81 100644 --- a/eng/restore-toolset.ps1 +++ b/eng/restore-toolset.ps1 @@ -4,6 +4,8 @@ function InitializeCustomSDKToolset { Write-Host "INFO: Tests will run against full MSBuild in $env:DOTNET_SDK_TEST_MSBUILD_PATH" } + EnablePreviewSdks + if (-not $restore) { return } From a82d8d9bbd4a795981d531928730e888b4d851c7 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 5 Nov 2025 10:46:03 -0800 Subject: [PATCH 06/13] consider that vs tool may not exist? also, why doesn't exist? maybe we call it too early? try calling it again in sdk tests as well --- build/sdktests.ps1 | 4 ++-- eng/common/tools.ps1 | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/build/sdktests.ps1 b/build/sdktests.ps1 index 84a1b03a0a1f..c86257bb394b 100644 --- a/build/sdktests.ps1 +++ b/build/sdktests.ps1 @@ -7,7 +7,7 @@ Param( [string] $tests = "", [Parameter(ValueFromRemainingArguments=$true)][String[]]$additionalRunParams ) - +EnablePreviewSdks Set-StrictMode -Version 2.0 $ErrorActionPreference = "Stop" @@ -52,7 +52,7 @@ if ($run) foreach ( $name in $testNames ) { $cmd = "testSdk$name" - + & $cmd -xml ($name + "results.xml") $additionalRunParams if ($LASTEXITCODE -ne 0) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 0123624a0a90..80ac2f853cfb 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -547,19 +547,25 @@ function LocateVisualStudio([object]$vsRequirements = $null){ }) } - if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs } + if (!$vsRequirements) { + if (Get-Member -InputObject $GlobalJson.tools -Name 'vs' -ErrorAction SilentlyContinue) { + $vsRequirements = $GlobalJson.tools.vs + } else { + $vsRequirements = $null + } + } $args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*') if (!$excludePrereleaseVS) { $args += '-prerelease' } - if (Get-Member -InputObject $vsRequirements -Name 'version') { + if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'version' -ErrorAction SilentlyContinue)) { $args += '-version' $args += $vsRequirements.version } - if (Get-Member -InputObject $vsRequirements -Name 'components') { + if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'components' -ErrorAction SilentlyContinue)) { foreach ($component in $vsRequirements.components) { $args += '-requires' $args += $component From eaa36c73d70536d51c21004bc13f1c966461324f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 5 Nov 2025 10:49:05 -0800 Subject: [PATCH 07/13] also allow pre-release in main global.json --- global.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 8d0dd39886de..48408909355c 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,9 @@ { "tools": { - "dotnet": "9.0.111", + "dotnet": { + "version": "9.0.111", + "allowPrerelease": true + }, "runtimes": { "dotnet": [ "$(VSRedistCommonNetCoreSharedFrameworkx6490PackageVersion)" @@ -22,4 +25,4 @@ "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.DotNet.CMake.Sdk": "9.0.0-beta.24217.1" } -} +} \ No newline at end of file From 0b089d56ab47893b9542578feeb4a90e2978a881 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 5 Nov 2025 16:57:50 -0800 Subject: [PATCH 08/13] move allowprerelrease to sdk root json node --- global.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/global.json b/global.json index 48408909355c..76431c49c6ff 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,9 @@ { "tools": { "dotnet": { - "version": "9.0.111", + "version": "9.0.111" + }, + "sdk": { "allowPrerelease": true }, "runtimes": { From fd4017b59526636bdeed019c5f52b00652da81da Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 5 Nov 2025 17:01:12 -0800 Subject: [PATCH 09/13] apparently there's a 'dotnet' node --- global.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/global.json b/global.json index 76431c49c6ff..92ab3ab340d3 100644 --- a/global.json +++ b/global.json @@ -1,8 +1,6 @@ { "tools": { - "dotnet": { - "version": "9.0.111" - }, + "dotnet": "9.0.111", "sdk": { "allowPrerelease": true }, From 35bae26db217ce9b7775f2175b6730968d9998a9 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 6 Nov 2025 09:15:34 -0800 Subject: [PATCH 10/13] Set MSBuildSDKsPath Based on the code in msbuild for the sdk resolver, this seemed to be what took effect the most to me. I think \r is likely correct, considering we also set DOTNET_SDK_TEST_MSBUILDSDKRESOLVER_FOLDER to the \r folder. What is surprising to me is that, that is not working. The dotnet on the PATH is also found but not by msbuild. I assume that this may mean it's VS who is rejecting the SDK, which would mean an environment variable won't be enough unless it's able to turn off the preview sdks disable check. I'll try to find the code for that or get the enable preview sdks bit to work inside of helix --- build/RunTestsOnHelix.cmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index eecd11ef4382..b9b3b8c73887 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -6,7 +6,8 @@ set NUGET_EXPERIMENTAL_NETWORK_RETRY_DELAY_MILLISECONDS=1000 set MicrosoftNETBuildExtensionsTargets=%HELIX_CORRELATION_PAYLOAD%\ex\msbuildExtensions\Microsoft\Microsoft.NET.Build.Extensions\Microsoft.NET.Build.Extensions.targets set DOTNET_ROOT=%HELIX_CORRELATION_PAYLOAD%\d -set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\d +set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=%HELIX_CORRELATION_PAYLOAD%\r +set MSBuildSDKsPath=%HELIX_CORRELATION_PAYLOAD%\r set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 From 9165c0136889c108f5d6cfc51e45be4cea639cbb Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 6 Nov 2025 09:40:22 -0800 Subject: [PATCH 11/13] Try to force VS to enable preview SDKs this is what the roslyn code was doing but I didnt realize. Looking at the vscode, it's literally just this .txt file which decides how to reject or accept preview SDKs. --- build/RunTestsOnHelix.cmd | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index b9b3b8c73887..1ac77496b10d 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -12,6 +12,17 @@ set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 +REM Ensure Visual Studio instances allow preview SDKs +PowerShell -ExecutionPolicy ByPass -Command ^ + "$vsRoot = Join-Path $env:USERPROFILE 'AppData\Local\Microsoft\VisualStudio'; ^ + if (Test-Path $vsRoot) { ^ + Get-ChildItem -Path $vsRoot -Directory | Where-Object { $_.Name -like '*.0_*' } | ForEach-Object { ^ + $null = New-Item -ItemType Directory -Path $_.FullName -Force; ^ + $sdkFile = Join-Path $_.FullName 'sdk.txt'; ^ + 'UsePreviews=True' | Set-Content -Path $sdkFile -Encoding ASCII ^ + } ^ + }" + REM Use powershell to call partical Arcade logic to get full framework msbuild path and assign it if "%TestFullMSBuild%"=="true" ( FOR /F "tokens=*" %%g IN ('PowerShell -ExecutionPolicy ByPass -File "%HELIX_CORRELATION_PAYLOAD%\t\eng\print-full-msbuild-path.ps1"') do (SET DOTNET_SDK_TEST_MSBUILD_PATH=%%g) From 0311c567063a18a0a77a6c1c17b2dbc7bb18807d Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 6 Nov 2025 09:43:07 -0800 Subject: [PATCH 12/13] Fix formatting will try to make this not ugly later --- build/RunTestsOnHelix.cmd | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index 1ac77496b10d..1be9739a17f4 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -13,15 +13,7 @@ set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 REM Ensure Visual Studio instances allow preview SDKs -PowerShell -ExecutionPolicy ByPass -Command ^ - "$vsRoot = Join-Path $env:USERPROFILE 'AppData\Local\Microsoft\VisualStudio'; ^ - if (Test-Path $vsRoot) { ^ - Get-ChildItem -Path $vsRoot -Directory | Where-Object { $_.Name -like '*.0_*' } | ForEach-Object { ^ - $null = New-Item -ItemType Directory -Path $_.FullName -Force; ^ - $sdkFile = Join-Path $_.FullName 'sdk.txt'; ^ - 'UsePreviews=True' | Set-Content -Path $sdkFile -Encoding ASCII ^ - } ^ - }" +PowerShell -ExecutionPolicy ByPass -NoProfile -Command " $vsRoot = Join-Path $env:USERPROFILE 'AppData\Local\Microsoft\VisualStudio'; if (Test-Path $vsRoot) { Get-ChildItem -Path $vsRoot -Directory | Where-Object { $_.Name -like '*.0_*' } | ForEach-Object { $instanceDir = $_.FullName; New-Item -ItemType Directory -Path $instanceDir -Force | Out-Null; 'UsePreviews=True' | Set-Content -Path (Join-Path $instanceDir 'sdk.txt') -Encoding ASCII } }" REM Use powershell to call partical Arcade logic to get full framework msbuild path and assign it if "%TestFullMSBuild%"=="true" ( From c762b23e62aa628b06db3f4cd8908ec3a8098866 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Thu, 6 Nov 2025 12:45:07 -0800 Subject: [PATCH 13/13] try to detect vs version folder in case it doesn't exist --- build/RunTestsOnHelix.cmd | 2 +- eng/EnablePreviewSdks.ps1 | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 eng/EnablePreviewSdks.ps1 diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index 1be9739a17f4..b092458272ca 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -13,7 +13,7 @@ set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 REM Ensure Visual Studio instances allow preview SDKs -PowerShell -ExecutionPolicy ByPass -NoProfile -Command " $vsRoot = Join-Path $env:USERPROFILE 'AppData\Local\Microsoft\VisualStudio'; if (Test-Path $vsRoot) { Get-ChildItem -Path $vsRoot -Directory | Where-Object { $_.Name -like '*.0_*' } | ForEach-Object { $instanceDir = $_.FullName; New-Item -ItemType Directory -Path $instanceDir -Force | Out-Null; 'UsePreviews=True' | Set-Content -Path (Join-Path $instanceDir 'sdk.txt') -Encoding ASCII } }" +PowerShell -ExecutionPolicy ByPass -NoProfile -File "%HELIX_CORRELATION_PAYLOAD%\t\eng\EnablePreviewSdks.ps1" REM Use powershell to call partical Arcade logic to get full framework msbuild path and assign it if "%TestFullMSBuild%"=="true" ( diff --git a/eng/EnablePreviewSdks.ps1 b/eng/EnablePreviewSdks.ps1 new file mode 100644 index 000000000000..19c9ae8f71d9 --- /dev/null +++ b/eng/EnablePreviewSdks.ps1 @@ -0,0 +1,33 @@ +param() + +$RepoRoot = Split-Path -Parent $PSScriptRoot +if (-not $RepoRoot) { + throw "Unable to determine repository root." +} + +. "$PSScriptRoot\common\tools.ps1" + +try { + $vsInfo = LocateVisualStudio +} +catch { + Write-Host "LocateVisualStudio failed: $_" + return +} + +if ($null -eq $vsInfo) { + Write-Host "No Visual Studio instance detected; preview SDKs remain enabled by default." + return +} + +$vsId = $vsInfo.instanceId +$vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] +$instanceDir = Join-Path $env:USERPROFILE "AppData\Local\Microsoft\VisualStudio\$vsMajorVersion.0_$vsId" + +Create-Directory $instanceDir + +$sdkFile = Join-Path $instanceDir 'sdk.txt' +'UsePreviews=True' | Set-Content -Path $sdkFile -Encoding ASCII + +Write-Host "Updated $sdkFile" +Get-Content -Path $sdkFile | ForEach-Object { Write-Host " $_" }