mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
fix: work around Consolonia libcoreclr.so DllNotFoundException on Linux single-file publish
Consolonia's Unix.Terminal uses [DllImport("libcoreclr.so")] to load
dlopen/dlsym on .NET Core. It ships a SetDllImportResolver that maps
the library name to the current process handle, but the resolver is
guarded by #if NET6_0 (exact TFM match) instead of NET6_0_OR_GREATER.
Since Consolonia targets net8.0, the resolver is never compiled in.
On self-contained single-file publishes, libcoreclr.so is bundled
inside the host binary and does not exist on disk. Without the
resolver the OS linker cannot find it, causing a DllNotFoundException
that crashes the TUI on startup. This primarily affects ARM64 Linux
users (e.g. Raspberry Pi / Debian Trixie) who almost exclusively use
self-contained publishes.
This commit registers an AssemblyLoadContext.Default.ResolvingUnmanagedDll
handler in Program.Main (before TUI init) that returns (IntPtr)(-1) for
libcoreclr.so, which the runtime interprets as the current process.
This is a temporary workaround until the upstream fix lands:
https://github.com/Consolonia/Consolonia/pull/605
Made-with: Cursor
This commit is contained in:
parent
82ebdd00ee
commit
115a6f0fcc
1 changed files with 25 additions and 0 deletions
|
|
@ -4,6 +4,8 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -174,6 +176,9 @@ namespace MinecraftClient
|
|||
};
|
||||
|
||||
// --- Determine console mode and initialize backend ---
|
||||
if (!OperatingSystem.IsWindows())
|
||||
InstallCursesNativeResolver();
|
||||
|
||||
if (!ConsoleIO.BasicIO && Config.Console.General.ConsoleMode == ConsoleModeType.tui)
|
||||
{
|
||||
ConsoleIO.Backend?.Shutdown();
|
||||
|
|
@ -206,6 +211,26 @@ namespace MinecraftClient
|
|||
RunStartupSequence(args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consolonia's Unix.Terminal uses <c>[DllImport("libcoreclr.so")]</c> to reach
|
||||
/// <c>dlopen</c>/<c>dlsym</c> on .NET Core. The library ships a
|
||||
/// <c>SetDllImportResolver</c> that maps <c>libcoreclr.so</c> to the current
|
||||
/// process, but it is compiled under <c>#if NET6_0</c> (exact TFM match) instead
|
||||
/// of <c>NET6_0_OR_GREATER</c>, so it is dead code when the consuming project
|
||||
/// targets net8.0+. On a self-contained single-file publish the physical
|
||||
/// <c>libcoreclr.so</c> does not exist on the search path, causing a
|
||||
/// <c>DllNotFoundException</c> that crashes the TUI.
|
||||
///
|
||||
/// We work around this by registering our own resolver before any Consolonia
|
||||
/// code runs: if any assembly asks for <c>libcoreclr.so</c> we return
|
||||
/// <c>(IntPtr)(-1)</c> which the runtime interprets as "the current process".
|
||||
/// </summary>
|
||||
private static void InstallCursesNativeResolver()
|
||||
{
|
||||
AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, libraryName) =>
|
||||
libraryName == "libcoreclr.so" ? (IntPtr)(-1) : IntPtr.Zero;
|
||||
}
|
||||
|
||||
private static void HandleTuiStartupFailure(Exception exception)
|
||||
{
|
||||
Config.Console.General.ConsoleMode = ConsoleModeType.classic;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue