.NET 6.0动态生成C#控制台程序遇System.Private.CoreLib加载异常
问题:生成的C#控制台程序运行时无法加载System.Private.CoreLib
编译生成的GeneratedExecutable.exe运行时抛出错误:
Could not load file or assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'
用于生成程序的代码如下:
static void Main(string[] args) { string code = @" using System; class Program { static void Main() { Console.WriteLine(""Hello, World!""); } }"; string outputPath = Path.Combine(Path.GetTempPath(), "GeneratedExecutable.exe"); GenerateExecutable(code, outputPath); } private static void GenerateExecutable(string code, string outputPath) { var stringText = SourceText.From(code, Encoding.UTF8); var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(stringText, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10), outputPath); var metaDataReference = new List<MetadataReference>(); metaDataReference.Add(MetadataReference.CreateFromFile(typeof(Object).Assembly.Location)); metaDataReference.Add(MetadataReference.CreateFromFile(typeof(Console).Assembly.Location)); var s = MetadataReference.CreateFromFile(Assembly.Load(Assembly.GetEntryAssembly().GetReferencedAssemblies().Single(a => a.Name == "System.Runtime") ).Location); metaDataReference.Add(s); var defaultCompilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication) .WithUsings(new string[] { "System" }); var compilation = CSharpCompilation.Create(Path.GetFileName(outputPath), new SyntaxTree[] { parsedSyntaxTree }, metaDataReference, defaultCompilationOptions); var result = compilation.Emit(outputPath); Console.WriteLine("Compilation OK : "+result.Success.ToString()); }
原因分析
这个错误是因为编译时引用的程序集与目标运行时环境不匹配。在.NET Core/.NET 5+生态中,System.Private.CoreLib是承载核心类型的基础库,但原代码的引用方式没有正确关联到对应版本的该库,同时编译选项未明确指定目标框架版本,导致生成的程序在运行时无法找到正确版本的依赖库。
解决方案
调整程序集引用逻辑,并明确编译的目标框架,确保生成的可执行文件匹配运行时环境:
- 确保核心库
System.Private.CoreLib被正确引用; - 用
WithTargetFramework指定目标框架版本,让编译器生成匹配的程序集; - 补充必要的基础程序集引用,避免依赖缺失。
修改后的代码如下:
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; class Program { static void Main(string[] args) { string code = @" using System; class Program { static void Main() { Console.WriteLine(""Hello, World!""); } }"; string outputPath = Path.Combine(Path.GetTempPath(), "GeneratedExecutable.exe"); GenerateExecutable(code, outputPath); } private static void GenerateExecutable(string code, string outputPath) { var stringText = SourceText.From(code, Encoding.UTF8); var parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10); var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(stringText, parseOptions); var metaDataReferences = new List<MetadataReference>(); // 添加核心库System.Private.CoreLib的引用 var coreLib = typeof(object).Assembly; metaDataReferences.Add(MetadataReference.CreateFromFile(coreLib.Location)); // 添加System.Console所在的程序集 var consoleLib = typeof(Console).Assembly; metaDataReferences.Add(MetadataReference.CreateFromFile(consoleLib.Location)); // 添加System.Runtime引用 var runtimeLib = Assembly.Load("System.Runtime"); metaDataReferences.Add(MetadataReference.CreateFromFile(runtimeLib.Location)); // 指定目标框架(示例为net6.0,可根据实际环境调整) var compilationOptions = new CSharpCompilationOptions(OutputKind.ConsoleApplication) .WithUsings(new[] { "System" }) .WithTargetFramework(TargetFrameworkMoniker.Net60); var compilation = CSharpCompilation.Create( Path.GetFileName(outputPath), new[] { parsedSyntaxTree }, metaDataReferences, compilationOptions); var emitResult = compilation.Emit(outputPath); if (emitResult.Success) { Console.WriteLine("编译成功!可执行文件路径:" + outputPath); } else { Console.WriteLine("编译失败:"); foreach (var diagnostic in emitResult.Diagnostics) { Console.WriteLine(diagnostic.ToString()); } } } }
关键修改点说明
- 明确指定
TargetFrameworkMoniker(如Net60),让编译器生成对应框架的可执行文件; - 简化程序集引用的获取逻辑,确保核心库和依赖库都被正确关联;
- 添加编译错误诊断输出,方便排查编译阶段的潜在问题。
内容的提问来源于stack exchange,提问作者Sybaris
相关产品推荐
相关产品推荐

