The console does not contain a definition for ReadKey when using Roslyn

I am trying to dynamically compile code and execute it at runtime. So I followed http://www.tugberkugurlu.com/archive/compiling-c-sharp-code-into-memory-and-executing-it-with-roslyn as a guide.

The code in the example works prefect. However, if I use Console.ReadKey(), this gives me an error CS0117: 'Console' does not contain a definition for 'ReadKey'. I read somewhere that this is because the dotnet kernel does not support ReadKey( "Console" does not contain a definition for "ReadKey" in asp.net 5 console application ), but I am currently using "Microsoft.NETCore.App"it and it Console.ReadKey()works fine if I use it explicitly in code instead of using Roslyn.

  • Is this a problem with Roslyn, or am I doing something wrong?
  • It is there "Microsoft.NETCore.App"and dotnet corethe same thing? I suspect that I can use something else as my target (which allows me to use ReadKey) and the dotnet core with Roslyn
  • Can Roslyn's goal be changed to something else?

Thanks in advance.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;

namespace DemoCompiler
{
    class Program
    {
        public static void roslynCompile()
        {
            string code = @"
    using System;
    using System.Text;

    namespace RoslynCompileSample
    {
        public class Writer
        {
            public void Write(string message)
            {
                Console.WriteLine(message);
                Console.ReadKey();
            }
        }
    }";
            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);

            string assemblyName = Path.GetRandomFileName();
            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location)
            };

            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic => 
                        diagnostic.IsWarningAsError || 
                        diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                        Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
                    var type= assembly.GetType("RoslynCompileSample.Writer");
                    var instance = assembly.CreateInstance("RoslynCompileSample.Writer");
                    var meth = type.GetMember("Write").First() as MethodInfo;
                    meth.Invoke(instance, new [] {assemblyName});
                }
            }

        }
    }
}

Edit: I tried to reference System.Console.dll, but I had a conflict between this and System.Private.CoreLib. How to resolve it?

+4
source share
2 answers

A similar issue was found in https://github.com/dotnet/roslyn/issues/13267 with the solution.

I have this (as far as I can tell):

System.Runtime.dll System.Runtime.Extensions.dll : C:\Users\<user>\.nuget\packages\System.Runtime\4.1.0\ref\netstandard1.5 "" . mscorlib.dll System.Private.CoreLib.dll

System.Runtime.dll ( , ). , MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location) MetadataReference.CreateFromFile("System.Runtime.dll"), DLL, .

, DLL , , , Roslyn .net , .net

0

, <PreserveCompilationContext>true</PreserveCompilationContext> * , Microsoft.Extensions.DependencyModel.DependencyContext, :

var references = DependencyContext.Default.CompileLibraries
    .SelectMany(l => l.ResolveReferencePaths())
    .Select(l => MetadataReference.CreateFromFile(l));

, , , , :

warning CS1701: , "System.Runtime, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a", "System.Console", "System.Runtime, Version = 4.1.0.0, Culture = , PublicKeyToken = b03f5f7f11d50a3a '' System.Runtime ',

, .


* , csproj/VS2017. project.json/VS2015, , "buildOptions": { "preserveCompilationContext": true }.

0

Source: https://habr.com/ru/post/1672167/


All Articles