From 437521c79733527b649480abe45b70c5460674c1 Mon Sep 17 00:00:00 2001 From: jycr <51145+jycr@users.noreply.github.com> Date: Mon, 12 Oct 2026 17:24:36 +0200 Subject: [PATCH 1/3] aspnetcore-runtime: Add version 10.0.12 Closes #18999 --- bucket/aspnetcore-runtime.json | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 bucket/aspnetcore-runtime.json diff --git a/bucket/aspnetcore-runtime.json b/bucket/aspnetcore-runtime.json new file mode 100644 index 00000000000000..f77785c852d280 --- /dev/null +++ b/bucket/aspnetcore-runtime.json @@ -0,0 +1,49 @@ +{ + "version": "10.0.12", + "description": "Microsoft ASP.NET Core (10.0 latest) Runtime, including the .NET Runtime, installed from the ZIP archive without admin rights", + "homepage": "https://dotnet.microsoft.com/download/dotnet", + "license": "MIT", + "suggest": { + "vcredist": "extras/vcredist2022" + }, + "architecture": { + "64bit": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/10.0.12/aspnetcore-runtime-10.0.12-win-x64.zip", + "hash": "sha512:b6958736bd42eff9c78a27a489d43eb0a39c6201039070ecb76a93cb96c519f07c86fa8b62034c6dd1a82a4c8ad0bd781e052008a7ec4cc48f9f792227d9c7ac" + }, + "32bit": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/10.0.12/aspnetcore-runtime-10.0.12-win-x86.zip", + "hash": "sha512:248012bb409f9f6ee369c45832f5f20b66e765290572454cc475534ce64878edb5f38ec936d28cce42f4f9a2ba1654dd8238d8f91e5e01e3d4f70585cbe1d329" + }, + "arm64": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/10.0.12/aspnetcore-runtime-10.0.12-win-arm64.zip", + "hash": "sha512:d18b4c3015698ea64cdb3581d52984b3477703bd7e59600b88341343b5f35f6d8f8d353ecc560a2586c79796abef73d36c8fc0ccec954da8bebe8b49f3e032b9" + } + }, + "env_add_path": ".", + "env_set": { + "DOTNET_ROOT": "$dir" + }, + "checkver": { + "url": "https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json", + "jsonpath": "$.releases-index[?(@.support-phase == 'active')].latest-runtime", + "regex": "([\\d.]+)" + }, + "autoupdate": { + "architecture": { + "64bit": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$version/aspnetcore-runtime-$version-win-x64.zip" + }, + "32bit": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$version/aspnetcore-runtime-$version-win-x86.zip" + }, + "arm64": { + "url": "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$version/aspnetcore-runtime-$version-win-arm64.zip" + } + }, + "hash": { + "url": "https://builds.dotnet.microsoft.com/dotnet/release-metadata/$majorVersion.$minorVersion/releases.json", + "regex": "(?s)$basename.*?$sha512" + } + } +} From 7a1750e42257cd497560693a51a7ec791684216c Mon Sep 17 00:00:00 2001 From: jycr <51145+jycr@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:25:22 +0200 Subject: [PATCH 2/3] aspnetcore-runtime: Allow side-by-side installation with dotnet-runtime and dotnetN-runtime DOTNET_ROOT was set to $dir, so it was overwritten or wiped by other .NET runtime packages, and the runtime bundled in the ASP.NET Core zip could not be shared safely. Expose the runtime in a common root, \shared\dotnet, shared by all .NET runtime packages (junctions to each package's versioned directories). An existing valid link is kept (first owner wins) and re-linked to another installed package on uninstall; DOTNET_ROOT is restored after uninstall while the root still exists. --- bucket/aspnetcore-runtime.json | 48 +++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/bucket/aspnetcore-runtime.json b/bucket/aspnetcore-runtime.json index f77785c852d280..57829139107153 100644 --- a/bucket/aspnetcore-runtime.json +++ b/bucket/aspnetcore-runtime.json @@ -1,6 +1,6 @@ { "version": "10.0.12", - "description": "Microsoft ASP.NET Core (10.0 latest) Runtime, including the .NET Runtime, installed from the ZIP archive without admin rights", + "description": "Microsoft ASP.NET Core Runtime, including the .NET Runtime, installed from the ZIP archive without admin rights", "homepage": "https://dotnet.microsoft.com/download/dotnet", "license": "MIT", "suggest": { @@ -20,10 +20,52 @@ "hash": "sha512:d18b4c3015698ea64cdb3581d52984b3477703bd7e59600b88341343b5f35f6d8f8d353ecc560a2586c79796abef73d36c8fc0ccec954da8bebe8b49f3e032b9" } }, - "env_add_path": ".", + "post_install": [ + "# Link this runtime into the root shared by all .NET packages (side-by-side)", + "$root = Join-Path (basedir $global) 'shared\\dotnet'", + "foreach ($d in Get-ChildItem \"$original_dir\\host\\fxr\\*\", \"$original_dir\\shared\\*\\*\" -Directory) {", + " $link = Join-Path $root $d.FullName.Substring($original_dir.Length + 1)", + " New-Item -ItemType Directory -Force (Split-Path $link) | Out-Null", + " $old = Get-Item $link -Force -ErrorAction SilentlyContinue", + " if ($old -and (Test-Path $link)) { continue }", + " if ($old) { [IO.Directory]::Delete($link) }", + " New-Item -ItemType Junction -Path $link -Target $d.FullName | Out-Null", + "}", + "$exe = \"$root\\dotnet.exe\"", + "if (!(Test-Path $exe) -or (Get-Item $exe).VersionInfo.FileMajorPart -lt (Get-Item \"$original_dir\\dotnet.exe\").VersionInfo.FileMajorPart) {", + " Copy-Item \"$original_dir\\dotnet.exe\" $exe -Force", + "}", + "New-Item -ItemType Junction -Path \"$original_dir\\dotnet-root\" -Target $root | Out-Null" + ], + "env_add_path": "dotnet-root", "env_set": { - "DOTNET_ROOT": "$dir" + "DOTNET_ROOT": "$(basedir $global)\\shared\\dotnet" }, + "pre_uninstall": [ + "# Unlink this package's runtimes, handing each over to another installed package that provides it", + "$root = Join-Path (basedir $global) 'shared\\dotnet'", + "if (Get-Item \"$dir\\dotnet-root\" -Force -ErrorAction SilentlyContinue) { [IO.Directory]::Delete(\"$dir\\dotnet-root\") }", + "if (Test-Path $root) {", + " $pattern = \"$root\\host\\fxr\\*\", \"$root\\shared\\*\\*\"", + " $owned = Get-ChildItem $pattern -Directory | Where-Object { \"$($_.Target)\".StartsWith(\"$dir\\\", 'OrdinalIgnoreCase') }", + " $others = Get-ChildItem (Join-Path (appsdir $global) '*\\current') -ErrorAction SilentlyContinue | Where-Object { $_.Parent.FullName -ne (Split-Path $dir) }", + " foreach ($l in $owned) {", + " $rel = $l.FullName.Substring($root.Length + 1)", + " [IO.Directory]::Delete($l.FullName)", + " $src = $others | ForEach-Object { Join-Path \"$($_.Target)\" $rel } | Where-Object { Test-Path $_ } | Select-Object -First 1", + " if ($src) { New-Item -ItemType Junction -Path $l.FullName -Target $src | Out-Null }", + " }", + " if (!(Get-ChildItem $pattern -Directory)) { Remove-Item $root -Recurse -Force }", + "}" + ], + "post_uninstall": [ + "# env_set removal wiped DOTNET_ROOT; restore it while another runtime remains", + "$root = Join-Path (basedir $global) 'shared\\dotnet'", + "if (Test-Path $root) {", + " Set-EnvVar -Name 'DOTNET_ROOT' -Value $root -Global:$global", + " $env:DOTNET_ROOT = $root", + "}" + ], "checkver": { "url": "https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json", "jsonpath": "$.releases-index[?(@.support-phase == 'active')].latest-runtime", From 476c8968b1766db1174f47ec2c05dd6bc236dc7a Mon Sep 17 00:00:00 2001 From: jycr <51145+jycr@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:58:18 +0200 Subject: [PATCH 3/3] aspnetcore-runtime: Fix review comments on side-by-side install - Compare the full dotnet.exe file version instead of the major only - Find replacement runtimes in installed version dirs when NO_JUNCTION is set - Stop recursively deleting the shared dotnet root; remove only empty dirs --- bucket/aspnetcore-runtime.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/bucket/aspnetcore-runtime.json b/bucket/aspnetcore-runtime.json index 57829139107153..0513fc08bccbdd 100644 --- a/bucket/aspnetcore-runtime.json +++ b/bucket/aspnetcore-runtime.json @@ -32,7 +32,7 @@ " New-Item -ItemType Junction -Path $link -Target $d.FullName | Out-Null", "}", "$exe = \"$root\\dotnet.exe\"", - "if (!(Test-Path $exe) -or (Get-Item $exe).VersionInfo.FileMajorPart -lt (Get-Item \"$original_dir\\dotnet.exe\").VersionInfo.FileMajorPart) {", + "if (!(Test-Path $exe) -or (Get-Item $exe).VersionInfo.FileVersionRaw -lt (Get-Item \"$original_dir\\dotnet.exe\").VersionInfo.FileVersionRaw) {", " Copy-Item \"$original_dir\\dotnet.exe\" $exe -Force", "}", "New-Item -ItemType Junction -Path \"$original_dir\\dotnet-root\" -Target $root | Out-Null" @@ -48,14 +48,19 @@ "if (Test-Path $root) {", " $pattern = \"$root\\host\\fxr\\*\", \"$root\\shared\\*\\*\"", " $owned = Get-ChildItem $pattern -Directory | Where-Object { \"$($_.Target)\".StartsWith(\"$dir\\\", 'OrdinalIgnoreCase') }", - " $others = Get-ChildItem (Join-Path (appsdir $global) '*\\current') -ErrorAction SilentlyContinue | Where-Object { $_.Parent.FullName -ne (Split-Path $dir) }", + " $others = Get-ChildItem (Join-Path (appsdir $global) '*\\*') -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Parent.FullName -ne (Split-Path $dir) } | Sort-Object { $_.Name -ne 'current' }", " foreach ($l in $owned) {", " $rel = $l.FullName.Substring($root.Length + 1)", " [IO.Directory]::Delete($l.FullName)", - " $src = $others | ForEach-Object { Join-Path \"$($_.Target)\" $rel } | Where-Object { Test-Path $_ } | Select-Object -First 1", + " $src = $others | ForEach-Object { Join-Path $(if ($_.Target) { \"$($_.Target)\" } else { $_.FullName }) $rel } | Where-Object { Test-Path $_ } | Select-Object -First 1", " if ($src) { New-Item -ItemType Junction -Path $l.FullName -Target $src | Out-Null }", " }", - " if (!(Get-ChildItem $pattern -Directory)) { Remove-Item $root -Recurse -Force }", + " if (!(Get-ChildItem $pattern -Directory)) {", + " if (!(Test-Path \"$root\\sdk\")) { Remove-Item \"$root\\dotnet.exe\" -Force -ErrorAction SilentlyContinue }", + " foreach ($p in \"$root\\host\\fxr\", \"$root\\shared\\*\", \"$root\\host\", \"$root\\shared\", $root) {", + " Get-Item $p -ErrorAction SilentlyContinue | Where-Object { !(Get-ChildItem $_.FullName -Force) } | Remove-Item", + " }", + " }", "}" ], "post_uninstall": [