Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b580f1a
install non nighly runtimes with dotnetup over install script
nagilson Jan 26, 2026
1bb6dcb
Merge remote-tracking branch 'origin/nagilson-dnup-install-runtimes-i…
nagilson Jan 27, 2026
88efa72
Use `dotnetup` on linux too
nagilson Jan 27, 2026
f86b4dd
embed pdb files to maintain single file executable
nagilson Jan 27, 2026
ecbd34c
don't assume x64 win
nagilson Jan 27, 2026
a044222
try to embed all languages instead of only en
nagilson Jan 27, 2026
c6ae215
force en for single file
nagilson Jan 27, 2026
38f56e6
Merge branch 'release/dnup' into nagilson-sdk-uses-dnup-for-core-runt…
nagilson Feb 6, 2026
a50b0e8
dont include pdb but also don't generate many resx files to be sing…
nagilson Feb 6, 2026
15e47ca
Fix documentation (idk how this was missed before, thanks)
nagilson Feb 9, 2026
8f00e4a
More explicit path call to dotnet
nagilson Feb 9, 2026
6a826cf
doc fix
nagilson Feb 9, 2026
b8e332a
don't set invariant globalzn - resource copy is an aot bug https://gi…
nagilson Feb 9, 2026
71e0494
Don't install .0 versions
nagilson Feb 9, 2026
183089d
--install-path shouldn't fail if it conflicts with the globaljson
nagilson Feb 9, 2026
367cd1f
Revert "--install-path shouldn't fail if it conflicts with the global…
nagilson Feb 9, 2026
bc48943
Merge branch 'release/dnup' into nagilson-sdk-uses-dnup-for-core-runt…
nagilson Feb 19, 2026
b386597
bug fix - don't grab composite archives or use aspnet hash for core h…
nagilson Feb 19, 2026
564ee28
dont download apphost packs - better errors for validation failure
nagilson Feb 19, 2026
fdd01e1
tests for app host pack in manifest
nagilson Feb 19, 2026
320fd04
dont auto decompress - it messes up the sha
nagilson Feb 20, 2026
43c08f0
work for other powershell installs besides pwsh
nagilson Feb 19, 2026
5eadd92
Fix for release
nagilson Feb 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ cmake/
# Helix payload
.dotnet.payload

# dotnetup build output
eng/dotnetup/

# MSBuild Logs
**/MSBuild_Logs/MSBuild_pid-*.failure.txt

Expand Down
243 changes: 134 additions & 109 deletions eng/restore-toolset.ps1
Original file line number Diff line number Diff line change
@@ -1,45 +1,74 @@
function InitializeCustomSDKToolset {
if ($env:TestFullMSBuild -eq "true") {
$env:DOTNET_SDK_TEST_MSBUILD_PATH = InitializeVisualStudioMSBuild -install:$true -vsRequirements:$GlobalJson.tools.'vs-opt'
Write-Host "INFO: Tests will run against full MSBuild in $env:DOTNET_SDK_TEST_MSBUILD_PATH"
}

if (-not $restore) {
return
}

# The following frameworks and tools are used only for testing.
# Do not attempt to install them when building in the VMR.
if ($fromVmr) {
return
}

$cli = InitializeDotnetCli -install:$true
InstallDotNetSharedFramework "6.0.0"
InstallDotNetSharedFramework "7.0.0"
InstallDotNetSharedFramework "8.0.0"
InstallDotNetSharedFramework "9.0.0"

CreateBuildEnvScripts
CreateVSShortcut
InstallNuget
if ($env:TestFullMSBuild -eq "true") {
$env:DOTNET_SDK_TEST_MSBUILD_PATH = InitializeVisualStudioMSBuild -install:$true -vsRequirements:$GlobalJson.tools.'vs-opt'
Write-Host "INFO: Tests will run against full MSBuild in $env:DOTNET_SDK_TEST_MSBUILD_PATH"
}

if (-not $restore) {
return
}

# The following frameworks and tools are used only for testing.
# Do not attempt to install them when building in the VMR.
if ($fromVmr) {
return
}

$cli = InitializeDotnetCli -install:$true

# Build dotnetup if not already present (needs SDK to be installed first)
EnsureDotnetupBuilt

InstallDotNetSharedFramework "6.0"
InstallDotNetSharedFramework "7.0"
InstallDotNetSharedFramework "8.0"
InstallDotNetSharedFramework "9.0"

CreateBuildEnvScripts
CreateVSShortcut
InstallNuget
}

function EnsureDotnetupBuilt {
$dotnetupExe = Join-Path $PSScriptRoot "dotnetup\dotnetup.exe"

if (!(Test-Path $dotnetupExe)) {
Write-Host "Building dotnetup..."
$dotnetupProject = Join-Path $RepoRoot "src\Installer\dotnetup\dotnetup.csproj"
$dotnetupOutDir = Join-Path $PSScriptRoot "dotnetup"

# Determine RID based on architecture
$rid = if ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) {
"win-arm64"
}
else {
"win-x64"
}

& (Join-Path $env:DOTNET_INSTALL_DIR 'dotnet.exe') publish $dotnetupProject -c Release -r $rid -o $dotnetupOutDir

if ($lastExitCode -ne 0) {
throw "Failed to build dotnetup (exit code '$lastExitCode')."
}

Write-Host "dotnetup built successfully"
}
}

function InstallNuGet {
$NugetInstallDir = Join-Path $ArtifactsDir ".nuget"
$NugetExe = Join-Path $NugetInstallDir "nuget.exe"
$NugetInstallDir = Join-Path $ArtifactsDir ".nuget"
$NugetExe = Join-Path $NugetInstallDir "nuget.exe"

if (!(Test-Path -Path $NugetExe)) {
Create-Directory $NugetInstallDir
Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -UseBasicParsing -OutFile $NugetExe
}
if (!(Test-Path -Path $NugetExe)) {
Create-Directory $NugetInstallDir
Invoke-WebRequest "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -UseBasicParsing -OutFile $NugetExe
}
}

function CreateBuildEnvScripts()
{
Create-Directory $ArtifactsDir
$scriptPath = Join-Path $ArtifactsDir "sdk-build-env.bat"
$scriptContents = @"
function CreateBuildEnvScripts() {
Create-Directory $ArtifactsDir
$scriptPath = Join-Path $ArtifactsDir "sdk-build-env.bat"
$scriptContents = @"
@echo off
title SDK Build ($RepoRoot)
set DOTNET_MULTILEVEL_LOOKUP=0
Expand All @@ -56,11 +85,11 @@ set DOTNET_ADD_GLOBAL_TOOLS_TO_PATH=0
DOSKEY killdotnet=taskkill /F /IM dotnet.exe /T ^& taskkill /F /IM VSTest.Console.exe /T ^& taskkill /F /IM msbuild.exe /T
"@

Out-File -FilePath $scriptPath -InputObject $scriptContents -Encoding ASCII
Out-File -FilePath $scriptPath -InputObject $scriptContents -Encoding ASCII

Create-Directory $ArtifactsDir
$scriptPath = Join-Path $ArtifactsDir "sdk-build-env.ps1"
$scriptContents = @"
Create-Directory $ArtifactsDir
$scriptPath = Join-Path $ArtifactsDir "sdk-build-env.ps1"
$scriptContents = @"
`$host.ui.RawUI.WindowTitle = "SDK Build ($RepoRoot)"
`$env:DOTNET_MULTILEVEL_LOOKUP=0
# https://aka.ms/vs/unsigned-dotnet-debugger-lib
Expand All @@ -80,89 +109,85 @@ function killdotnet {
}
"@

Out-File -FilePath $scriptPath -InputObject $scriptContents -Encoding ASCII
Out-File -FilePath $scriptPath -InputObject $scriptContents -Encoding ASCII
}

function CreateVSShortcut()
{
# https://github.com/microsoft/vswhere/wiki/Installing
$installerPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
if(-Not (Test-Path -Path $installerPath))
{
return
}

$versionFilePath = Join-Path $RepoRoot 'src\Layout\redist\minimumMSBuildVersion'
# Gets the first digit (ex. 17) and appends '.0' to it.
$vsMajorVersion = "$(((Get-Content $versionFilePath).Split('.'))[0]).0"
$devenvPath = (& "$installerPath\vswhere.exe" -all -prerelease -latest -version $vsMajorVersion -find Common7\IDE\devenv.exe) | Select-Object -First 1
if(-Not $devenvPath)
{
return
}

$scriptPath = Join-Path $ArtifactsDir 'sdk-build-env.ps1'
$slnPath = Join-Path $RepoRoot 'sdk.slnx'
$commandToLaunch = "& '$scriptPath'; & '$devenvPath' '$slnPath'"
$powershellPath = '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe'
$shortcutPath = Join-Path $ArtifactsDir 'VS with sdk.slnx.lnk'

# https://stackoverflow.com/a/9701907/294804
# https://learn.microsoft.com/en-us/troubleshoot/windows-client/admin-development/create-desktop-shortcut-with-wsh
$wsShell = New-Object -ComObject WScript.Shell
$shortcut = $wsShell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = $powershellPath
$shortcut.Arguments = "-WindowStyle Hidden -ExecutionPolicy Bypass -Command ""$commandToLaunch"""
$shortcut.IconLocation = $devenvPath
$shortcut.WindowStyle = 7 # Minimized
$shortcut.Save()
function CreateVSShortcut() {
# https://github.com/microsoft/vswhere/wiki/Installing
$installerPath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer"
if (-Not (Test-Path -Path $installerPath)) {
return
}

$versionFilePath = Join-Path $RepoRoot 'src\Layout\redist\minimumMSBuildVersion'
# Gets the first digit (ex. 17) and appends '.0' to it.
$vsMajorVersion = "$(((Get-Content $versionFilePath).Split('.'))[0]).0"
$devenvPath = (& "$installerPath\vswhere.exe" -all -prerelease -latest -version $vsMajorVersion -find Common7\IDE\devenv.exe) | Select-Object -First 1
if (-Not $devenvPath) {
return
}

$scriptPath = Join-Path $ArtifactsDir 'sdk-build-env.ps1'
$slnPath = Join-Path $RepoRoot 'sdk.slnx'
$commandToLaunch = "& '$scriptPath'; & '$devenvPath' '$slnPath'"
$powershellPath = '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe'
$shortcutPath = Join-Path $ArtifactsDir 'VS with sdk.slnx.lnk'

# https://stackoverflow.com/a/9701907/294804
# https://learn.microsoft.com/en-us/troubleshoot/windows-client/admin-development/create-desktop-shortcut-with-wsh
$wsShell = New-Object -ComObject WScript.Shell
$shortcut = $wsShell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = $powershellPath
$shortcut.Arguments = "-WindowStyle Hidden -ExecutionPolicy Bypass -Command ""$commandToLaunch"""
$shortcut.IconLocation = $devenvPath
$shortcut.WindowStyle = 7 # Minimized
$shortcut.Save()
}

function InstallDotNetSharedFramework([string]$version) {
$dotnetRoot = $env:DOTNET_INSTALL_DIR
$fxDir = Join-Path $dotnetRoot "shared\Microsoft.NETCore.App\$version"
$dotnetRoot = $env:DOTNET_INSTALL_DIR
$fxDir = Join-Path $dotnetRoot "shared\Microsoft.NETCore.App\$version"

if (!(Test-Path $fxDir)) {
$dotnetupExe = Join-Path $PSScriptRoot "dotnetup\dotnetup.exe"

if (!(Test-Path $fxDir)) {
$installScript = GetDotNetInstallScript $dotnetRoot
& $installScript -Version $version -InstallDir $dotnetRoot -Runtime "dotnet" -SkipNonVersionedFiles
& $dotnetupExe runtime install "$version" --install-path $dotnetRoot --no-progress --set-default-install false

if($lastExitCode -ne 0) {
throw "Failed to install shared Framework $version to '$dotnetRoot' (exit code '$lastExitCode')."
if ($lastExitCode -ne 0) {
throw "Failed to install shared Framework $version to '$dotnetRoot' using dotnetup (exit code '$lastExitCode')."
}
}
}
}

# Let's clear out the stage-zero folders that map to the current runtime to keep stage 2 clean
function CleanOutStage0ToolsetsAndRuntimes {
$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json
$dotnetSdkVersion = $GlobalJson.tools.dotnet
$dotnetRoot = $env:DOTNET_INSTALL_DIR
$versionPath = Join-Path $dotnetRoot '.version'
$aspnetRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared' ,'Microsoft.AspNetCore.App')
$coreRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared' ,'Microsoft.NETCore.App')
$wdRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared', 'Microsoft.WindowsDesktop.App')
$sdkPath = Join-Path $dotnetRoot 'sdk'
$majorVersion = $dotnetSdkVersion.Substring(0,1)

if (Test-Path($versionPath)) {
$lastInstalledSDK = Get-Content -Raw -Path ($versionPath)
if ($lastInstalledSDK -ne $dotnetSdkVersion)
{
$dotnetSdkVersion | Out-File -FilePath $versionPath -NoNewline
Remove-Item (Join-Path $aspnetRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $coreRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $wdRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $sdkPath "*") -Recurse
Remove-Item (Join-Path $dotnetRoot "packs") -Recurse
Remove-Item (Join-Path $dotnetRoot "sdk-manifests") -Recurse
Remove-Item (Join-Path $dotnetRoot "templates") -Recurse
throw "Installed a new SDK, deleting existing shared frameworks and sdk folders. Please rerun build"
$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json
$dotnetSdkVersion = $GlobalJson.tools.dotnet
$dotnetRoot = $env:DOTNET_INSTALL_DIR
$versionPath = Join-Path $dotnetRoot '.version'
$aspnetRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared' , 'Microsoft.AspNetCore.App')
$coreRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared' , 'Microsoft.NETCore.App')
$wdRuntimePath = [IO.Path]::Combine( $dotnetRoot, 'shared', 'Microsoft.WindowsDesktop.App')
$sdkPath = Join-Path $dotnetRoot 'sdk'
$majorVersion = $dotnetSdkVersion.Substring(0, 1)

if (Test-Path($versionPath)) {
$lastInstalledSDK = Get-Content -Raw -Path ($versionPath)
if ($lastInstalledSDK -ne $dotnetSdkVersion) {
$dotnetSdkVersion | Out-File -FilePath $versionPath -NoNewline
Remove-Item (Join-Path $aspnetRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $coreRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $wdRuntimePath "$majorVersion.*") -Recurse
Remove-Item (Join-Path $sdkPath "*") -Recurse
Remove-Item (Join-Path $dotnetRoot "packs") -Recurse
Remove-Item (Join-Path $dotnetRoot "sdk-manifests") -Recurse
Remove-Item (Join-Path $dotnetRoot "templates") -Recurse
throw "Installed a new SDK, deleting existing shared frameworks and sdk folders. Please rerun build"
}
}
else {
$dotnetSdkVersion | Out-File -FilePath $versionPath -NoNewline
}
}
else
{
$dotnetSdkVersion | Out-File -FilePath $versionPath -NoNewline
}
}

InitializeCustomSDKToolset
Expand Down
56 changes: 48 additions & 8 deletions eng/restore-toolset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,69 @@ function InitializeCustomSDKToolset {

InitializeDotNetCli true

InstallDotNetSharedFramework "6.0.0"
InstallDotNetSharedFramework "7.0.0"
InstallDotNetSharedFramework "8.0.0"
InstallDotNetSharedFramework "9.0.0"
# Build dotnetup if not already present (needs SDK to be installed first)
EnsureDotnetupBuilt

InstallDotNetSharedFramework "6.0"
InstallDotNetSharedFramework "7.0"
InstallDotNetSharedFramework "8.0"
InstallDotNetSharedFramework "9.0"

CreateBuildEnvScript
}

# Builds dotnetup if the executable doesn't exist
function EnsureDotnetupBuilt {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local dotnetup_dir="$script_dir/dotnetup"
local dotnetup_exe="$dotnetup_dir/dotnetup"

if [[ ! -f "$dotnetup_exe" ]]; then
echo "Building dotnetup..."
local dotnetup_project="$repo_root/src/Installer/dotnetup/dotnetup.csproj"

# Determine RID based on OS
local rid
if [[ "$(uname)" == "Darwin" ]]; then
if [[ "$(uname -m)" == "arm64" ]]; then
rid="osx-arm64"
else
rid="osx-x64"
fi
else
if [[ "$(uname -m)" == "aarch64" ]]; then
rid="linux-arm64"
else
rid="linux-x64"
fi
fi

"$DOTNET_INSTALL_DIR/dotnet" publish "$dotnetup_project" -c Release -r "$rid" -o "$dotnetup_dir"

if [[ $? -ne 0 ]]; then
echo "Failed to build dotnetup."
ExitWithExitCode 1
fi

echo "dotnetup built successfully"
fi
}

# Installs additional shared frameworks for testing purposes
function InstallDotNetSharedFramework {
local version=$1
local dotnet_root=$DOTNET_INSTALL_DIR
local fx_dir="$dotnet_root/shared/Microsoft.NETCore.App/$version"

if [[ ! -d "$fx_dir" ]]; then
GetDotNetInstallScript "$dotnet_root"
local install_script=$_GetDotNetInstallScript
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local dotnetup_exe="$script_dir/dotnetup/dotnetup"

bash "$install_script" --version $version --install-dir "$dotnet_root" --runtime "dotnet" --skip-non-versioned-files
"$dotnetup_exe" runtime install "$version" --install-path "$dotnet_root" --no-progress --set-default-install false
local lastexitcode=$?

if [[ $lastexitcode != 0 ]]; then
echo "Failed to install Shared Framework $version to '$dotnet_root' (exit code '$lastexitcode')."
echo "Failed to install Shared Framework $version to '$dotnet_root' using dotnetup (exit code '$lastexitcode')."
ExitWithExitCode $lastexitcode
fi
fi
Expand Down
Loading
Loading