You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug B (main only, from Default Architecture to OS arch for UsingTask Runtime="NET" #13741):GetExplicitMSBuildArchitecture(arch, runtime) returns "*" for unspecified arch under .NET Framework + Runtime="NET". The PR description says it returns the OS architecture, but the implementation returns MSBuildArchitectureValues.any. The handshake then emits no arch bit, which hits Bug A on Windows-ARM and regresses the ARM64 .NET Framework parent case (which previously worked via symmetric match).
Symptom
Roslyn's build.cmd on Windows-ARM against SDK 10.0.108:
error MSB4216: Could not run the "CompareVersions" task because MSBuild could not create or
connect to a task host with runtime "NET" and architecture "*". Please ensure that
(1) the requested runtime and/or architecture are available on the machine, and
(2) that the required executable "C:\Program Files\dotnet\sdk\10.0.108\MSBuild.exe" exists
and can be run.
Two caveats on the message:
The MSBuild.exe path is a template in TaskHostTask.LogErrorUnableToCreateTaskHost — emitted regardless of whether the parent actually launches the apphost. SDK 10.0.108 ships MSBuild.dll only; the apphost first ships in 10.0.300. The apphost-vs-dotnet.exe MSBuild.dll decision doesn't affect the handshake.
The arch "*" is the puzzle that points at Bug B — release branches normalize it to a concrete arch in MergeTaskFactoryParameterSets. Worth confirming which MSBuild binary Roslyn's environment actually invokes.
receivedIsX86 correctly excludes both X64 and Arm64. expectedIsX64 forgets Arm64. The function always returns false when the child expects Arm64 (i.e. whenever the SDK runs on a Windows-ARM machine and the parent sent no arch bit).
Introduced by #11393. Present on main, vs17.14, vs17.15, vs18.0, vs18.3–vs18.7. Windows-ARM has never worked through this code path.
Bug B — GetExplicitMSBuildArchitecture(arch, runtime) returns "*" instead of OS arch
src/Framework/XMakeAttributes.cs:496-508, introduced by #13741. Call site is AssemblyTaskFactory.MergeTaskFactoryParameterSets.
The PR description states:
When runtime == "NET" and architecture is unspecified (* / CurrentArchitecture / null), returns the OS architecture (which matches the dotnet host that will actually be launched) instead of the current process architecture.
It returns "any" ("*"), not the OS arch. GetHandshakeOptions only sets X64/Arm64 bits when arch equals "x64"/"arm64" — "*" produces no bit. The parent then sends a handshake indistinguishable from an x86 parent, which lands on Bug A.
ARM64 .NET Framework parent regression (VS Desktop 17.10+ on Windows-ARM)
The change is observable in the bytes on the wire, not just internal representation.
x86 / amd64 .NET Framework parent on Windows-x64
Wire bit is the same (none) before and after #13741, because "x86"/"amd64" already produced no X64/Arm64 bit. Bug A's tolerance covers expected=X64, so this path keeps working — no behavior change from #13741 here.
So Roslyn's failure on SDK 10.0.108 (whose MSBuild is a vs18.0 build) is pure Bug A. The "*" in the error string suggests the parent actually doing the build may be a main-built MSBuild on PATH; on release branches MergeTaskFactoryParameterSets would normalize the arch to a concrete value before logging.
Proposed fixes
Fix A — child-side tolerance (main + service to vs18.0)
This single change unblocks Windows-ARM on every branch. Safe to service to vs18.0 for an SDK 10.0.x patch — only widens what is currently rejected, no payload format change.
Fix B — make #13741's implementation match its description (main only)
Return the OS architecture (per the PR description) when the current process arch is x64 or arm64; only fall back to "any" for an x86 .NET Framework parent (where no x86 SDK exists and Bug A's tolerance is the right answer). This also undoes the ARM64 .NET Fx parent regression without giving up #13741's intent.
A cleaner long-term option: have the parent compute the wire arch bit from the apphost RID / SDK layout it is about to launch, so the child always sees a concrete bit and IsAllowedBitnessMismatch becomes vestigial.
Tests to add
IsAllowedBitnessMismatch unit test with expected = Arm64, received = (no arch bit) → true.
GetExplicitMSBuildArchitecture(arch, runtime) matrix covering {null, "*", "x86", "x64", "arm64"} × {"CLR4", "NET", null} on x86 / x64 / arm64 hosts. Currently no arm64 coverage.
Summary
<UsingTask Runtime="NET" />fails withMSB4216on Windows-ARM. Two independent bugs:IsAllowedBitnessMismatchonly toleratesexpected=X64, notexpected=Arm64. Any cross-bitness NET task host handshake to an ARM64 child is rejected.mainonly, from Default Architecture to OS arch for UsingTask Runtime="NET" #13741):GetExplicitMSBuildArchitecture(arch, runtime)returns"*"for unspecified arch under .NET Framework + Runtime="NET". The PR description says it returns the OS architecture, but the implementation returnsMSBuildArchitectureValues.any. The handshake then emits no arch bit, which hits Bug A on Windows-ARM and regresses the ARM64 .NET Framework parent case (which previously worked via symmetric match).Symptom
Roslyn's
build.cmdon Windows-ARM against SDK 10.0.108:Two caveats on the message:
MSBuild.exepath is a template inTaskHostTask.LogErrorUnableToCreateTaskHost— emitted regardless of whether the parent actually launches the apphost. SDK 10.0.108 shipsMSBuild.dllonly; the apphost first ships in 10.0.300. The apphost-vs-dotnet.exe MSBuild.dlldecision doesn't affect the handshake."*"is the puzzle that points at Bug B — release branches normalize it to a concrete arch inMergeTaskFactoryParameterSets. Worth confirming which MSBuild binary Roslyn's environment actually invokes.Bug A —
IsAllowedBitnessMismatchArm64 gapsrc/Shared/NodeEndpointOutOfProcBase.cs:590-602:receivedIsX86correctly excludes bothX64andArm64.expectedIsX64forgetsArm64. The function always returnsfalsewhen the child expectsArm64(i.e. whenever the SDK runs on a Windows-ARM machine and the parent sent no arch bit).Introduced by #11393. Present on
main,vs17.14,vs17.15,vs18.0,vs18.3–vs18.7. Windows-ARM has never worked through this code path.Bug B —
GetExplicitMSBuildArchitecture(arch, runtime)returns"*"instead of OS archsrc/Framework/XMakeAttributes.cs:496-508, introduced by #13741. Call site isAssemblyTaskFactory.MergeTaskFactoryParameterSets.The PR description states:
The shipped code:
It returns
"any"("*"), not the OS arch.GetHandshakeOptionsonly setsX64/Arm64bits when arch equals"x64"/"arm64"—"*"produces no bit. The parent then sends a handshake indistinguishable from an x86 parent, which lands on Bug A.ARM64 .NET Framework parent regression (VS Desktop 17.10+ on Windows-ARM)
normalizedArchfor<UsingTask Runtime="NET" />"arm64"(GetCurrentMSBuildArchitecture)"*"GetHandshakeOptionswire bitArm64Arm64Arm64The change is observable in the bytes on the wire, not just internal representation.
x86 / amd64 .NET Framework parent on Windows-x64
Wire bit is the same (
none) before and after #13741, because"x86"/"amd64"already produced noX64/Arm64bit. Bug A's tolerance coversexpected=X64, so this path keeps working — no behavior change from #13741 here.Branch / parent matrix on Windows-ARM
main(post-#13741)vs18.x/vs17.x(no #13741)So Roslyn's failure on SDK 10.0.108 (whose MSBuild is a vs18.0 build) is pure Bug A. The
"*"in the error string suggests the parent actually doing the build may be amain-built MSBuild on PATH; on release branchesMergeTaskFactoryParameterSetswould normalize the arch to a concrete value before logging.Proposed fixes
Fix A — child-side tolerance (
main+ service tovs18.0)src/Shared/NodeEndpointOutOfProcBase.cs:This single change unblocks Windows-ARM on every branch. Safe to service to
vs18.0for an SDK 10.0.x patch — only widens what is currently rejected, no payload format change.Fix B — make #13741's implementation match its description (
mainonly)Return the OS architecture (per the PR description) when the current process arch is x64 or arm64; only fall back to
"any"for an x86 .NET Framework parent (where no x86 SDK exists and Bug A's tolerance is the right answer). This also undoes the ARM64 .NET Fx parent regression without giving up #13741's intent.A cleaner long-term option: have the parent compute the wire arch bit from the apphost RID / SDK layout it is about to launch, so the child always sees a concrete bit and
IsAllowedBitnessMismatchbecomes vestigial.Tests to add
IsAllowedBitnessMismatchunit test withexpected = Arm64,received = (no arch bit)→true.GetExplicitMSBuildArchitecture(arch, runtime)matrix covering{null, "*", "x86", "x64", "arm64"}×{"CLR4", "NET", null}on x86 / x64 / arm64 hosts. Currently no arm64 coverage.References
IsAllowedBitnessMismatch(Bug A origin).GetExplicitMSBuildArchitecture(arch, runtime)(Bug B origin). PR description vs implementation diverge.