.NET Core运行时编译C#代码遇System.PlatformNotSupportedException异常
解决.NET Core中运行时编译C#代码抛出PlatformNotSupportedException的问题
问题根源
CSharpCodeProvider与CodeDom.Compiler系列API是.NET Framework专属的编译工具链,在.NET Core/.NET 5+环境下完全不被支持——它们依赖旧框架的本地编译器,无法适配跨平台的.NET Core运行时,因此调用CompileAssemblyFromSource时会直接抛出PlatformNotSupportedException。
替代方案:使用Roslyn编译器API
Roslyn是官方原生的C#编译平台,提供了完整的跨平台运行时编译能力,完美适配.NET Core/.NET 5+环境。
步骤1:安装依赖包
在项目中添加Roslyn的核心NuGet包:
dotnet add package Microsoft.CodeAnalysis.CSharp
步骤2:替换原有编译代码
以下是用Roslyn重写的完整实现,和原代码逻辑一致但兼容.NET Core:
using System; using System.Reflection; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; string code = @" using System; namespace First { public class Program { public static void Main() { Console.WriteLine(""Hello, world!""); } } } "; // 1. 将字符串代码解析为语法树 SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code); // 2. 指定编译所需的依赖程序集 string[] referencePaths = new[] { typeof(object).Assembly.Location, // 基础类库 typeof(Console).Assembly.Location // 控制台类库 }; // 3. 配置编译参数并执行编译 CSharpCompilation compilation = CSharpCompilation.Create( assemblyName: "FirstRuntimeAssembly", syntaxTrees: new[] { syntaxTree }, references: referencePaths.Select(path => MetadataReference.CreateFromFile(path)), options: new CSharpCompilationOptions(OutputKind.ConsoleApplication) // 生成控制台可执行文件 ); // 将编译结果写入内存流 using var memoryStream = new System.IO.MemoryStream(); EmitResult emitResult = compilation.Emit(memoryStream); // 4. 检查编译错误 if (!emitResult.Success) { var errorMessages = string.Join(Environment.NewLine, emitResult.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error) .Select(d => $"{d.Id}: {d.GetMessage()}")); throw new InvalidOperationException($"编译失败:{Environment.NewLine}{errorMessages}"); } // 5. 加载程序集并执行Main方法 memoryStream.Seek(0, System.IO.SeekOrigin.Begin); Assembly compiledAssembly = Assembly.Load(memoryStream.ToArray()); Type programType = compiledAssembly.GetType("First.Program"); MethodInfo mainMethod = programType.GetMethod("Main", BindingFlags.Public | BindingFlags.Static); mainMethod.Invoke(null, null);
关键细节说明
- 程序集引用:需要明确指定编译代码依赖的程序集路径,若需使用
System.Drawing,需先安装System.Drawing.CommonNuGet包,再添加对应程序集的引用路径。 - 编译配置:
OutputKind.ConsoleApplication对应原代码的GenerateExecutable = true,编译结果写入内存流实现GenerateInMemory = true的效果。 - 错误排查:
EmitResult.Diagnostics会返回所有编译阶段的诊断信息,包括警告和错误,比旧CodeDom的错误提示更全面。
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

