Skip to content

Isolate child dotnet commands from unsafe MSBuild state - #376

Closed
OvesN wants to merge 2 commits into
jaredpar:mainfrom
OvesN:fix/isolate-child-dotnet-environment
Closed

Isolate child dotnet commands from unsafe MSBuild state#376
OvesN wants to merge 2 commits into
jaredpar:mainfrom
OvesN:fix/isolate-child-dotnet-environment

Conversation

@OvesN

@OvesN OvesN commented Aug 12, 2026

Copy link
Copy Markdown

Summary

  • refine Handle CryptoKeyFile from SolutionReader #375's blanket MSBuild* environment removal to a three-variable denylist
  • remove the two SDK-identifying paths that can mix parent targets/tasks with child MSBuild assemblies
  • preserve Handle CryptoKeyFile from SolutionReader #375's stdout-handle fix by removing MSBUILDENSURESTDOUTFORTASKPROCESSES
  • preserve platform-specific environment-name semantics and legitimate unrelated MSBuild settings
  • route exported-solution builds through the isolated launcher with the export directory as the working directory

Root cause

The .NET CLI sets MSBuildExtensionsPath and MSBuildSDKsPath for its selected SDK. A child dotnet command can select a different SDK based on its working directory and global.json roll-forward policy.

Inheriting those paths can combine targets and NuGet.Build.Tasks.dll from the parent SDK with Microsoft.Build.Framework from the child SDK. The mismatch became visible when newer NuGet tasks began implementing IMultiThreadableTask, producing MSB4062 type-load failures.

MSBUILDENSURESTDOUTFORTASKPROCESSES is a separate hazard: reusable MSBuild worker nodes inherit the redirected stdout handle, while ProcessUtil synchronously waits for stdout EOF. Removing it preserves the subprocess-hang fix introduced by #375.

The .NET 10.0.400 SDK bundle itself was verified to contain a matching Microsoft.Build.Framework; the type-load failure is caused by cross-SDK environment contamination rather than an inconsistent bundle.

Why an explicit denylist

PR #375 removed every variable beginning with MSBuild. This follow-up retains that fix's known unsafe variables while preserving unrelated MSBuild configuration such as MSBuildLoadMicrosoftTargetsReadOnly and MSBuildExtensionsPath32/MSBuildExtensionsPath64.

The denylist is intentionally explicit. Future SDK-injected variables that identify a parent SDK or alter redirected process lifetime should be evaluated and added when necessary.

Compatibility

This changes only internal process-launch behavior and restores the existing intent that child dotnet commands select a coherent SDK context. DOTNET_HOST_PATH remains preserved because it identifies the shared muxer.

Validation

  • dotnet build Basic.CompilerLog.slnx -warnaserror
  • focused net10.0 run covering SolutionReaderTests.CryptoKeyFile and every changed solution-build launch path: 22 passed, Unix-only environment-casing test skipped on Windows
  • focused net472 regression test

OvesN and others added 2 commits August 12, 2026 20:27
Remove SDK-specific MSBuild path overrides from child dotnet processes and route exported-solution builds through the isolated launcher.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8c8d3934-edc7-4f26-a1fc-451749254212
Preserve the 10.0.400 stdout-handle fix from PR jaredpar#375 while narrowing its blanket MSBuild environment filter to known unsafe variables.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8c8d3934-edc7-4f26-a1fc-451749254212
@OvesN
OvesN force-pushed the fix/isolate-child-dotnet-environment branch from 8bfb3a9 to 215d9f9 Compare August 12, 2026 19:15
@OvesN OvesN changed the title Isolate child dotnet commands from parent SDK paths Isolate child dotnet commands from unsafe MSBuild state Aug 12, 2026
@OvesN OvesN closed this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant