运行时从字符串到控制台 exe 的代码生成在 C# .NET6 中不起作用

Codegeneration at runtime from a string to console exe is not working in C# .NET6

我有一些代码必须能够在运行时生成控制台应用程序(使用 System.CodeDom 进行代码生成)。我已经做了很多次了,但是在 NET 6 中,现在我正在为它和新的 API 而苦苦挣扎。在下面的代码中,我尝试简单地从一个字符串进行编译。请参阅下面的静态 class 方法 Start() 然后应该生成应用程序。

编译看起来不错,最后没有错误。但是当启动生成的AppCodegenerated.exe时,它显示了一些引用异常System.Runtime。

请帮忙,有什么想法吗?已经研究了很多但找不到任何有用的解决方案..

//-

我使用了 Visual Studio 2022 / NET 6 和论文 Nuget 的:

using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
using System.Text;



namespace CompilerSimplified
{
    public static class Compiler
    {
        public static bool Start()
        {
            string FileName = "AppCodegenerated";
            string ExePath = AppDomain.CurrentDomain.BaseDirectory + @"\" + FileName + ".exe";
            string code = @"using System; Console.WriteLine(""Hello.""); Console.ReadLine(); ";


            // ------- References -------------
            // .net platform references
            List<MetadataReference> References = new List<MetadataReference>();
            foreach (var item in ReferenceAssemblies.Net60) // ReferenceAssemblies from Nuget: Basic.Reference.Assemblies;
                References.Add(item);

            // or tried this: loop manually through system platform 
            //string[] fileEntries = Directory.GetFiles(@"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref.0.0\ref\net6.0\", "*.dll");
            //foreach (string fileName in fileEntries)
            //    references.Add(MetadataReference.CreateFromFile(fileName));MetadataReference.CreateFromFile(fileName));
            // ------- References END -------------



            // delete existing file
            if (File.Exists(ExePath))
                File.Delete(ExePath);

            // compiler options
            CSharpCompilationOptions DefaultCompilationOptions =
                new CSharpCompilationOptions(outputKind: OutputKind.ConsoleApplication, platform: Platform.AnyCpu)
                .WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release);

            // encode soucre code
            string sourceCode = SourceText.From(code, Encoding.UTF8).ToString();

            // CSharp options
            var parsedSyntaxTree = Parse(sourceCode, "", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10));

            // compilation
            var compilation = CSharpCompilation.Create(FileName, new SyntaxTree[] { parsedSyntaxTree }, references: References, DefaultCompilationOptions);
            var result = compilation.Emit(ExePath);

            // return
            if (result.Success)
                return true;
            else
                return false;
        }

        private static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null)
        {
            var stringText = SourceText.From(text, Encoding.UTF8);
            return SyntaxFactory.ParseSyntaxTree(stringText, options, filename);
        }

    }
}

以上代码运行良好,没有错误,并将 AppCodegenerated.exe 导出到项目 /bin 文件夹中。

执行此生成的 AppCodegenerated.exe 在输出控制台上显示以下内容:

Unhandled exception: System.IO.FileNotFoundException: 
The file or assembly "System.Runtime, Version = 6.0.0.0, Culture = neutral, 
PublicKeyToken = b03f5f7f11d50a3a" or a dependency on it was not found. 
The system can not find the stated file.

不可能像上面的初始方法那样直接代码生成控制台应用程序。一种可能的解决方案是首先生成一个 dll(我在上面的示例代码中提到的工作正常),然后从那里将该 .dll 包含到一个 .exe 中,从那里功能可以 运行.