使用 CodeAnalysis CSharpScript (.NET Core) 执行用户代码



我正在尝试执行简单的用户公式。

我正在使用MS VS 2017 15.2(26430.16(,.NET Core 1.1。

我跟着: https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples

我创建了 ASP.NET 核心 Web 应用,添加了 NuGet 包:

Install-Package Microsoft.CodeAnalysis.CSharp.Scripting

但在那之后,该应用程序给出了一个错误:

An unhandled exception occurred while processing the request.
ArgumentException: Must include private members unless emitting a ref assembly.
Parameter name: IncludePrivateMembers
Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable<ResourceDescription> manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable<EmbeddedText> embeddedTexts, Stream metadataPEStream, CancellationToken cancellationToken)

在我添加之后

using Microsoft.CodeAnalysis.CSharp.Scripting;

object result = CSharpScript.EvaluateAsync("1 + 2");

但没有看到,所以我添加了

<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="2.3.1" />

在"MyProject.csproj"中。

但我有同样的错误。

有人可以帮助我吗?

更新 1:

叠:

Microsoft.CodeAnalysis.Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable<ResourceDescription> manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable<EmbeddedText> embeddedTexts, Stream metadataPEStream, CancellationToken cancellationToken)
Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRoslynCompilationService.Compile(RelativeFileInfo fileInfo, string compilationContent)
Microsoft.AspNetCore.Mvc.Razor.Internal.RazorCompilationService.Compile(RelativeFileInfo file)
Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.CreateCacheEntry(string relativePath, string normalizedPath, Func<RelativeFileInfo, CompilationResult> compile)
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.GetOrAdd(string relativePath, Func<RelativeFileInfo, CompilationResult> compile)
Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorPageFactoryProvider.CreateFactory(string relativePath)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.CreateCacheResult(HashSet<IChangeToken> expirationTokens, string relativePath, bool isMainPage)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.OnCacheMiss(ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.LocatePageFromViewLocations(ActionContext actionContext, string pageName, bool isMainPage)
Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.FindView(ActionContext context, string viewName, bool isMainPage)
Microsoft.AspNetCore.Mvc.ViewEngines.CompositeViewEngine.FindView(ActionContext context, string viewName, bool isMainPage)
Microsoft.AspNetCore.Mvc.ViewFeatures.Internal.ViewResultExecutor.FindView(ActionContext actionContext, ViewResult viewResult)
Microsoft.AspNetCore.Mvc.ViewResult+<ExecuteResultAsync>d__26.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeResultAsync>d__30.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextResultFilterAsync>d__28.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResultExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextResourceFilter>d__22.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeAsync>d__20.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware+<ExecuteWithFilter>d__7.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext()

更新 2:

最后我这样做了(没有包(:

string user_code = "1 + 2";
string code = $"int? r = {user_code};";
string codeToCompile = @"using System;
namespace RoslynCompile
{
public class Calculator
{
public int? Calculate()
{
" + code + @"
return r;
}
}
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);
string assemblyName = Path.GetRandomFileName();
MetadataReference[] references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)
};
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult emitResult = compilation.Emit(ms);
if (!emitResult.Success)
{
// some errors
IEnumerable<Diagnostic> failures = emitResult.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
}
else
{
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
var type = assembly.GetType("RoslynCompile.Calculator");
var instance = assembly.CreateInstance("RoslynCompile.Calculator");
var meth = type.GetMember("Calculate").First() as MethodInfo;
// get result
int? result = meth.Invoke(instance, null) as int?;
}
}

我不确定是什么原因导致此错误,但我们回滚到Microsoft.CodeAnalysis.CSharpv2.2.0

它似乎从v2.3.0开始发生.在撰写本文时,v2.3.1已出局,并且仍然导致此问题。

在 GitHub 上查看问题。

最新更新