Skip to content

Add muxer support for DOTNET_ROOT_REDIRECT_TARGET - #131983

Draft
JakeRadMSFT wants to merge 1 commit into
dotnet:mainfrom
JakeRadMSFT:dev/jakerad/dotnet-root-redirect-target
Draft

Add muxer support for DOTNET_ROOT_REDIRECT_TARGET#131983
JakeRadMSFT wants to merge 1 commit into
dotnet:mainfrom
JakeRadMSFT:dev/jakerad/dotnet-root-redirect-target

Conversation

@JakeRadMSFT

Copy link
Copy Markdown
Member

Summary

Add an opt-in muxer redirect that allows a user-selected .NET hive, such as the hive managed by dotnetup, to replace the physical system hive for both SDK and runtime resolution.

When DOTNET_ROOT_REDIRECT_TARGET is set, the dotnet muxer:

  • loads hostfxr from the selected hive
  • resolves SDKs and shared frameworks from that hive
  • applies the redirect to SDK commands and framework-dependent applications launched with dotnet app.dll
  • does not fall back to the physical/system hive when the selected hive cannot satisfy resolution

When the variable is not set, muxer behavior is unchanged.

User opt-in

This behavior is intentionally user opt-in. Setting DOTNET_ROOT_REDIRECT_TARGET means: treat this path as my central .NET hive instead of the hive containing the muxer found on PATH.

The system muxer may still be the executable found first on PATH, but after startup it behaves as though the selected hive were in its place. The physical system hive is not used as a fallback by design; falling back would allow command-line tools, agents, and IDE tooling to silently select different SDKs again.

dotnetup will own the opt-in experience and clearly communicate this behavior when enabling it. Disabling the integration consists of removing the setting, which restores existing muxer behavior.

Tooling experience

The broader goal is for command-line tools, agents, and C# Dev Kit to resolve the same current SDK from the user-managed hive.

Follow-up work outside this host change will:

  • make the opt-in and its no-fallback behavior clear in dotnetup
  • surface the selected hive and relevant resolution guidance in C# Dev Kit
  • help users update incompatible global.json files when appropriate, including using a roll-forward policy such as latestFeature so the latest compatible SDK in the managed hive can be selected

Normal global.json version, roll-forward, and sdk.paths behavior remains owned by the existing SDK resolver. This change relocates the muxer hive; it does not introduce a second SDK-selection policy.

Validation

  • native host build succeeds
  • redirect selects SDKs only from the target hive
  • redirect selects shared frameworks from the target hive
  • direct dotnet app.dll activation resolves against the target hive
  • --list-sdks and --list-runtimes report the target hive
  • an incomplete target fails without falling back to the source/system hive

Focused MuxerRedirect tests pass on macOS ARM64. The complete host suite requires the full CoreCLR product and pretest asset build, which was not available in the sparse prototype checkout.

Copilot AI review requested due to automatic review settings August 7, 2026 02:00
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in muxer redirect controlled by DOTNET_ROOT_REDIRECT_TARGET so dotnet can behave as if it were launched from a user-selected .NET hive (affecting hostfxr loading, SDK resolution, and framework resolution).

Changes:

  • Introduces DOTNET_ROOT_REDIRECT_TARGET_ENV_VAR constant in host utilities.
  • Updates muxer startup to use DOTNET_ROOT_REDIRECT_TARGET (validated absolute path) as the effective dotnet root.
  • Adds HostActivation.Tests coverage for SDK/framework resolution and “no fallback” behavior when the target hive is incomplete.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/native/corehost/hostmisc/utils.h Adds the DOTNET_ROOT_REDIRECT_TARGET env var macro used by the muxer.
src/native/corehost/dotnet/dotnet.cpp Applies the redirect at muxer startup by rebasing app_root before hostfxr + dotnet.dll resolution.
src/installer/tests/HostActivation.Tests/MuxerRedirect.cs Adds tests validating redirect precedence and no-fallback behavior.
Suppressed comments (2)

src/installer/tests/HostActivation.Tests/MuxerRedirect.cs:60

  • This assertion includes the resolved framework base path, which is derived from the muxer-computed dotnet root and may be normalized differently than _targetDotNet.BinPath (symlink resolution on Unix, long-path prefix on Windows). To keep the test stable while still proving redirection, assert the resolved framework name+version only.
                .Execute()
                .ShouldHaveResolvedFramework(Constants.MicrosoftNETCoreApp, TargetVersion, _targetDotNet.BinPath);
        }

src/installer/tests/HostActivation.Tests/MuxerRedirect.cs:74

  • Like the other tests in this file, this asserts the full redirect path string, but the muxer normalizes the path via pal::fullpath, so the emitted trace may not contain the exact emptyTarget string (symlink resolution / long-path prefix). Checking for the redirect trace prefix is enough here, since the primary assertion is that the command fails without listing the source SDK.
                .Should().Fail()
                .And.HaveStdErrContaining($"Redirecting dotnet root to [{emptyTarget}]")
                .And.NotHaveStdOutContaining(SourceVersion);

Comment on lines +46 to +49
.Should().Pass()
.And.HaveStdOutContaining($"{TargetVersion} [{Path.Combine(_targetDotNet.BinPath, "sdk")}")
.And.NotHaveStdOutContaining(SourceVersion)
.And.HaveStdErrContaining($"Redirecting dotnet root to [{_targetDotNet.BinPath}]");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants