Skip to content

Fix missing Mono.Posix.NETStandard assembly load on Windows ARM64#766

Draft
Copilot wants to merge 4 commits into
mainfrom
copilot/fix-missing-mono-posit-netstandard
Draft

Fix missing Mono.Posix.NETStandard assembly load on Windows ARM64#766
Copilot wants to merge 4 commits into
mainfrom
copilot/fix-missing-mono-posit-netstandard

Conversation

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown

Fix #765

On Windows ARM64 the CLI throws System.IO.FileNotFoundException for Mono.Posix.NETStandard during file monitoring, because the package (1.0.0) ships its managed assembly only under runtimes/{rid}/lib/netstandard2.0/ and provides no win-arm64 RID (only win-x64, win-x86, linux-*, osx); the top-level lib/ is net40-only. Since win-arm64's RID fallback graph is win-arm64 → win → any (never win-x64/win-x86), no managed asset resolves and the assembly fails to load as soon as Mono.Unix-referencing code (file collection/monitoring) is JIT compiled — even though those Unix paths never run on Windows.

Changes

  • Lib/Utils/MonoPosixAssemblyResolver.cs — new [ModuleInitializer] that registers an AssemblyLoadContext.Default.Resolving handler. It fires only when default resolution fails and loads the platform-independent managed Mono.Posix.NETStandard.dll from a runtime folder that actually ships with the app (preferring win-arm64, then win-x64, etc.). No effect on platforms where the assembly already resolves.
  • Lib/Utils/AssemblyInfo.cs — add InternalsVisibleTo("AsaTests").
  • Tests/MonoPosixAssemblyResolverTests.cs — cover path resolution (wrong name → null, no asset → null, shipped asset → path) plus a registration/load smoke test.

The resolver lives in the Lib, so both the CLI tool and consumers of the Microsoft.CST.AttackSurfaceAnalyzer library benefit.

internal static string? FindAssemblyPath(string baseDirectory, string? assemblyName)
{
    if (string.IsNullOrEmpty(baseDirectory) ||
        !string.Equals(assemblyName, MonoPosixAssemblyName, StringComparison.OrdinalIgnoreCase))
        return null;

    foreach (var rid in CandidateRuntimeIdentifiers) // win-arm64, win-x64, win-x86, linux-x64, linux-arm64, osx
    {
        var candidate = Path.Combine(baseDirectory, "runtimes", rid, "lib", "netstandard2.0",
                                     $"{MonoPosixAssemblyName}.dll");
        if (File.Exists(candidate)) return candidate;
    }
    return null;
}

Notes

  • A pure packaging fix (injecting a win-arm64 runtime asset) was explored but rejected: GenerateDepsFile reconciles runtime targets against project.assets.json and drops RIDs the package doesn't declare, so the entry never reaches deps.json. The runtime resolver is self-contained and independent of SDK internals.
  • The native MonoPosixHelper is intentionally not required on Windows — only the managed IL needs to load; the actual P/Invokes are gated to Linux/OSX.

Copilot AI assigned Copilot and gfs Jun 9, 2026
Copilot AI linked an issue Jun 9, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Fix missing Mono.Posix.NETStandard binary for Windows ARM64 Fix missing Mono.Posix.NETStandard assembly load on Windows ARM64 Jun 9, 2026
Copilot finished work on behalf of gfs June 9, 2026 19:29
Copilot AI requested a review from gfs June 9, 2026 19:29
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.

Missing Mono.Posix.NETStandard Windows ARM64 binary

2 participants