From f0e65c5c5791b16633cdeb8d8174020d2d6e10b7 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 7 Nov 2025 11:52:19 -0800 Subject: [PATCH 1/2] Set sdk.txt file to enable preview SDKs - VS uses the local appdata, VS versioned folder, sdk.txt file to determine whether or not to accept preview sdks - VS Release rejects preview SDKs by default which causes the msbuild sdk resolver to not find sdks, as msbuild respects the vs settings - This changes the vs settings to enable our internal SDKs to be found by msbuild when it's going under test. - Possible improvements: this PR assumes sdk.txt content ordering does not matter - based on VS code this appears to be true but could change in the future Also tried: - modifying global.json to enable preview sdks, which was not enough. some tests have a custom global.json and it seems to not take precedence setting env vars such as msbuildsdks which did not take precedence over the vs setting This commit is a condensed version of the work done in https://github.com/dotnet/sdk/pull/51591 and https://github.com/dotnet/sdk/pull/51598 --- build/RunTestsOnHelix.cmd | 3 ++ eng/enable-preview-sdks.ps1 | 59 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 eng/enable-preview-sdks.ps1 diff --git a/build/RunTestsOnHelix.cmd b/build/RunTestsOnHelix.cmd index f55fcf1ead42..3dc68bb7f8af 100644 --- a/build/RunTestsOnHelix.cmd +++ b/build/RunTestsOnHelix.cmd @@ -10,6 +10,9 @@ set PATH=%DOTNET_ROOT%;%PATH% set DOTNET_MULTILEVEL_LOOKUP=0 set TestFullMSBuild=%1 +REM Ensure Visual Studio instances allow preview SDKs +PowerShell -ExecutionPolicy ByPass -NoProfile -File "%HELIX_CORRELATION_PAYLOAD%\t\eng\enable-preview-sdks.ps1" + 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) diff --git a/eng/enable-preview-sdks.ps1 b/eng/enable-preview-sdks.ps1 new file mode 100644 index 000000000000..d21466f856da --- /dev/null +++ b/eng/enable-preview-sdks.ps1 @@ -0,0 +1,59 @@ +param() + +. $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' + +$desiredLine = 'UsePreviews=True' +$existingLines = @() + +if (Test-Path $sdkFile) { + $existingLines = @(Get-Content -Path $sdkFile -Encoding ASCII) +} + +# Determine how to place the UsePreviews flag based on existing content. +$replacementIndex = -1 +for ($i = 0; $i -lt $existingLines.Count; $i++) { + if ($existingLines[$i] -match '^UsePreviews=.*$') { + $replacementIndex = $i + break + } +} + +# Replace the existing line to enforce it as True +if ($replacementIndex -ge 0) { + $updatedLines = $existingLines + $updatedLines[$replacementIndex] = $desiredLine +} +elseif ($existingLines.Count -gt 0) { + # Write to the top of the file but keep the remaining portion (assumption: order does not matter to VS) + $updatedLines = @($desiredLine) + $existingLines +} +else { + # Write a whole new file + $updatedLines = @($desiredLine) +} + +Set-Content -Path $sdkFile -Value $updatedLines -Encoding ASCII + +Write-Host "Updated $sdkFile" +Get-Content -Path $sdkFile | ForEach-Object { Write-Host " $_" } From dc6680431cb127d2424dec29ffd8f7e3bf542f17 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Fri, 7 Nov 2025 13:33:12 -0800 Subject: [PATCH 2/2] Get global json tools vs by default when locating VS --- eng/common/tools.ps1 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 9b3ad8840fdb..01481d6e12cf 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) { @@ -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 @@ -610,7 +616,7 @@ function InitializeBuildTool() { } else { $initializeBuildToolFramework=$env:_OverrideArcadeInitializeBuildToolFramework } - + $buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = $initializeBuildToolFramework } } elseif ($msbuildEngine -eq "vs") { try {