简体   繁体   中英

System.TypeLoadException: Could not load type 'System.Object' from assembly 'System.Private.CoreLib' because the parent does not exist

We are generating code dynamically to produce a .NET Core console application and then compiling it using:

    var csharpParseOptions = new CSharpParseOptions(LanguageVersion.Latest);

    csharpParseOptions = csharpParseOptions.WithPreprocessorSymbols(new[] { "TRACE", "DEBUG" });

    var syntaxTree = CSharpSyntaxTree.ParseText(code, options: csharpParseOptions);
    var compilationUnitSyntax = syntaxTree.GetCompilationUnitRoot();

    var options = new CSharpCompilationOptions(OutputKind.ConsoleApplication, optimizationLevel: OptimizationLevel.Debug, platform: Platform.X64)
      .WithModuleName("TestConsole")
      .WithMetadataImportOptions(MetadataImportOptions.All)
      .WithDeterministic(true)
      .WithConcurrentBuild(true);

    var csharpCompilation = CSharpCompilation.Create(@"TestConsole", syntaxTrees: new[] { syntaxTree }, references: references, options: options);

We can then work without any problems against the generated assembly (in memory) obtained using:

    using (var memoryStream = new MemoryStream())
    {
      var emitResult = csharpCompilation.Emit(memoryStream);
      memoryStream.Position = 0; 
      _assembly = Assembly.Load(memoryStream.ToArray());
    }

However, when we write the console.exe to disk using:

    csharpCompilation.Emit(fileNameOnDisk, Path.Combine(Path.GetDirectoryName(fileNameOnDisk), Path.GetFileNameWithoutExtension(fileNameOnDisk)) + ".pdb");

and try to run it from there we get the following exception:

System.TypeLoadException: Could not load type 'System.Object' from assembly 'System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because the parent does not exist.

Copying the same generated code (Program.cs) into an empty Console project works perfectly but we notice that the size of the executable is significantly larger.

Does anyone have any ideas how to go about fixing this problem? Thanks.

I think your problem is the lack of runtime configuration. From what I read above if you add a file named testconsole.runtimeconfig.json with the following info or similar:

{
    "runtimeOptions": {
        "tfm": "net6.0",
        "framework": {
            "name": "Microsoft.NETCore.App",
            "version": "6.0.0"
        }
    }
}

You'll see that it runs. I'm also attaching a complete example with compilation.Emit that I validated in LINQPad . It does not require an additional file since it generates it in the example. Best of luck and hope it is still useful.

var tree = CSharpSyntaxTree.ParseText (@"class Program 
{
    static void Main() => System.Console.WriteLine (""Hello"");
}");

string trustedAssemblies = (string)AppContext.GetData ("TRUSTED_PLATFORM_ASSEMBLIES");
var trustedAssemblyPaths = trustedAssemblies.Split (Path.PathSeparator);
var references = trustedAssemblyPaths.Select (path => MetadataReference.CreateFromFile (path));

var compilation = CSharpCompilation
    .Create ("test")
    .WithOptions (new CSharpCompilationOptions (OutputKind.ConsoleApplication))
    .AddSyntaxTrees (tree)
    .AddReferences (references);

string outputPath = "test.dll";
Path.GetFullPath (outputPath).Dump();
EmitResult result = compilation.Emit (outputPath);
Console.WriteLine (result.Success);

File.WriteAllText ("test.runtimeconfig.json", @$"{{
    ""runtimeOptions"": {{
        ""tfm"": ""net{Environment.Version.Major}.{Environment.Version.Minor}"",
        ""framework"": {{
            ""name"": ""Microsoft.NETCore.App"",
            ""version"": ""{Environment.Version.Major}.{Environment.Version.Minor}.{Environment.Version.Build}""
        }}
    }}
}}");

// Execute the program we just compiled.
Util.Cmd (@"dotnet.exe", "\"" + Path.GetFullPath (outputPath) + "\"");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM