Skip to content

Commit b61238f

Browse files
authored
Merge pull request #1116 from sMartz1/fix/roslyn-missing-system-runtime-compilerservices-unsafe
fix(roslyn): install missing System.Runtime.CompilerServices.Unsafe v6 + surface inner errors
2 parents bbc4992 + 3b1d1aa commit b61238f

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

MCPForUnity/Editor/Setup/RoslynInstaller.cs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.IO;
33
using System.IO.Compression;
4+
using System.Reflection;
45
using UnityEditor;
56
using UnityEngine;
67
using UnityEngine.Networking;
@@ -13,19 +14,44 @@ public static class RoslynInstaller
1314

1415
private static readonly (string packageId, string version, string dllPath, string dllName)[] NuGetEntries =
1516
{
16-
("microsoft.codeanalysis.common", "4.12.0", "lib/netstandard2.0/Microsoft.CodeAnalysis.dll", "Microsoft.CodeAnalysis.dll"),
17-
("microsoft.codeanalysis.csharp", "4.12.0", "lib/netstandard2.0/Microsoft.CodeAnalysis.CSharp.dll","Microsoft.CodeAnalysis.CSharp.dll"),
18-
("system.collections.immutable", "8.0.0", "lib/netstandard2.0/System.Collections.Immutable.dll", "System.Collections.Immutable.dll"),
19-
("system.reflection.metadata", "8.0.0", "lib/netstandard2.0/System.Reflection.Metadata.dll", "System.Reflection.Metadata.dll"),
17+
("microsoft.codeanalysis.common", "4.12.0", "lib/netstandard2.0/Microsoft.CodeAnalysis.dll", "Microsoft.CodeAnalysis.dll"),
18+
("microsoft.codeanalysis.csharp", "4.12.0", "lib/netstandard2.0/Microsoft.CodeAnalysis.CSharp.dll", "Microsoft.CodeAnalysis.CSharp.dll"),
19+
("system.collections.immutable", "8.0.0", "lib/netstandard2.0/System.Collections.Immutable.dll", "System.Collections.Immutable.dll"),
20+
("system.reflection.metadata", "8.0.0", "lib/netstandard2.0/System.Reflection.Metadata.dll", "System.Reflection.Metadata.dll"),
21+
// Transitive dep of Microsoft.CodeAnalysis.* on netstandard2.0. Without it, Roslyn's StringTable
22+
// static cctor throws FileNotFoundException for v6.0.0.0 and every Roslyn entry point fails to
23+
// initialize. Unity ships a v4.x of this assembly which does NOT satisfy the v6 reference.
24+
("system.runtime.compilerservices.unsafe","6.0.0", "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", "System.Runtime.CompilerServices.Unsafe.dll"),
2025
};
2126

2227
public static bool IsInstalled()
2328
{
2429
string folder = Path.Combine(Application.dataPath, PluginsRelPath);
2530
foreach (var entry in NuGetEntries)
2631
{
27-
if (!File.Exists(Path.Combine(folder, entry.dllName)))
32+
string path = Path.Combine(folder, entry.dllName);
33+
if (!File.Exists(path))
2834
return false;
35+
36+
// Defense-in-depth: a stale DLL whose assembly version is older than what
37+
// Roslyn references (e.g. a v4.x System.Runtime.CompilerServices.Unsafe
38+
// shadowing the v6 we actually need) would still satisfy file-existence but
39+
// leave Roslyn unable to load. Compare the on-disk assembly version against
40+
// each entry's declared NuGet version, treating "older or unreadable" as not
41+
// installed so Install() can rewrite it.
42+
if (Version.TryParse(entry.version, out var requiredVersion))
43+
{
44+
try
45+
{
46+
var actual = AssemblyName.GetAssemblyName(path).Version;
47+
if (actual == null || actual < requiredVersion)
48+
return false;
49+
}
50+
catch
51+
{
52+
return false;
53+
}
54+
}
2955
}
3056
return true;
3157
}

MCPForUnity/Editor/Tools/ExecuteCode.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,13 @@ public static Assembly Compile(string source, string[] assemblyPaths, out List<s
672672
}
673673
catch (Exception e)
674674
{
675-
errors.Add($"Roslyn compilation error: {e.Message}");
675+
// Walk to the deepest cause: TargetInvocationException (and friends) wrap the real
676+
// failure inside .InnerException, and reporting only e.Message hides everything
677+
// useful (e.g. a missing transitive dep manifests as the generic "Exception has been
678+
// thrown by the target of an invocation.").
679+
Exception root = e;
680+
while (root.InnerException != null) root = root.InnerException;
681+
errors.Add($"Roslyn compilation error: {root.GetType().Name}: {root.Message}");
676682
return null;
677683
}
678684
}

0 commit comments

Comments
 (0)