簡體   English   中英

在運行時從字符串到控制台 exe 的代碼生成在 C# .NET6 中不起作用

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

我有一些代碼必須能夠在運行時生成控制台應用程序(使用 System.CodeDom 生成代碼)。 我已經這樣做了很多,但現在在 NET 6 中我正在努力解決這個問題和新的 API。 在下面的代碼中,我嘗試簡單地從字符串編譯。 請參見下面的 static 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\6.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在 output 控制台上顯示以下內容:

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(我在上面的示例代碼中提到的工作正常),然后從那里將 that.dll 包含到 a.exe 中,從中可以運行功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM