[英]'Console' does not contain a definition for 'ReadKey' in asp.net 5 console App
[英]Console does not contain a definition for ReadKey while using Roslyn
我試圖動態編譯代碼並在運行時執行它。 所以我按照http://www.tugberkugurlu.com/archive/compiling-c-sharp-code-into-memory-and-executing-it-with-roslyn作為指導。
示例中給出的代碼完美地起作用。 但是,如果我使用Console.ReadKey()
它會給我錯誤CS0117: 'Console' does not contain a definition for 'ReadKey'
。 我在某處讀到這是因為dotnet核心不支持ReadKey
( 'Console'在asp.net 5控制台應用程序中不包含'ReadKey'的定義 ),但我目前正在使用"Microsoft.NETCore.App"
和它Console.ReadKey()
如果我在代碼中顯式使用它而不是在使用Roslyn時, Console.ReadKey()
可以正常工作。
"Microsoft.NETCore.App"
和dotnet core
是一回事嗎? 我懷疑我可能正在使用其他東西作為我的目標(允許我使用ReadKey
)和dotnet核心與Roslyn 提前致謝。
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});
}
}
}
}
}
編輯:我試圖引用System.Console.dll
但我和System.Private.CoreLib
之間發生沖突。 我該如何解決?
一種方法是將<PreserveCompilationContext>true</PreserveCompilationContext>
*添加到項目文件中,然后使用Microsoft.Extensions.DependencyModel.DependencyContext
獲取當前項目的所有引用程序集:
var references = DependencyContext.Default.CompileLibraries
.SelectMany(l => l.ResolveReferencePaths())
.Select(l => MetadataReference.CreateFromFile(l));
這似乎可以避免您獲得的錯誤,但會導致以下警告:
警告CS1701:假設程序集引用'System.Runtime,Version = 4.0.0.0,Culture = neutral,'System.Console'使用的PublicKeyToken = b03f5f7f11d50a3a'匹配標識'System.Runtime,Version = 4.1.0.0,Culture = neutral,PublicKeyToken 'System.Runtime'的= b03f5f7f11d50a3a',您可能需要提供運行時策略
*這假設您正在使用csproj / VS2017。 如果您仍在使用project.json / VS2015,則可以使用"buildOptions": { "preserveCompilationContext": true }
完成相同的操作"buildOptions": { "preserveCompilationContext": true }
。
使用該解決方案在https://github.com/dotnet/roslyn/issues/13267上發現了類似的問題。
我已經解決了這個問題(據我所知):
從以下位置復制
System.Runtime.dll
和System.Runtime.Extensions.dll
:C:\\Users\\<user>\\.nuget\\packages\\System.Runtime\\4.1.0\\ref\\netstandard1.5
並將它們放在References文件夾中在我的項目中。 那么,而不是引用mscorlib.dll
和System.Private.CoreLib.dll
我引用這些
我試過這個並發現僅引用System.Runtime.dll
就足夠了(至少在我的情況下)。 為了清楚,我現在使用MetadataReference.CreateFromFile("System.Runtime.dll")
而不是MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location)
,它引用了工作目錄中的DLL。直。
唯一的缺點是我必須將dll與我的項目一起分發,但考慮到我現在可以在.net核心上正確使用Roslyn而不是將基本框架更改為完整.net,這是可以的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.