C# 在CSharpCompilation.net Core中未获取命名空间/引用
我有一个使用一些动态编译代码的项目,我正在从.net framework升级到.net core 3.1 我无法获取包含newtonsoft.json.dll的简单测试用例,并获取错误“找不到类型或命名空间名称'newtonsoft'。我在第一次尝试添加库时遇到类似问题,但通过使用当前加载的程序集()。使用“Core“我没有得到关于库的错误,但它不知道类型,就像它没有被加载一样 我尝试了使用项目库(注释掉)和直接指定它们,但都有相同的问题。要重新创建,请创建一个名为“TestScript”的新.netCore 3.1控制台应用程序,并安装nuget软件包“Microsoft.CodeAnalysis.CSharp.Scripting”v3.7.0,“Newtonsoft.Json”v12.0.3,然后使用以下代码C# 在CSharpCompilation.net Core中未获取命名空间/引用,c#,.net-core,roslyn,roslyn-code-analysis,C#,.net Core,Roslyn,Roslyn Code Analysis,我有一个使用一些动态编译代码的项目,我正在从.net framework升级到.net core 3.1 我无法获取包含newtonsoft.json.dll的简单测试用例,并获取错误“找不到类型或命名空间名称'newtonsoft'。我在第一次尝试添加库时遇到类似问题,但通过使用当前加载的程序集()。使用“Core“我没有得到关于库的错误,但它不知道类型,就像它没有被加载一样 我尝试了使用项目库(注释掉)和直接指定它们,但都有相同的问题。要重新创建,请创建一个名为“TestScript”的新.
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
namespace TestScript
{
class Program
{
public static void Example1()
{
var assemblyName = "UserScript";
var code = @"namespace UserScript
{
using System;
using System.IO;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public class RunScript
{
private const int x = 99;
public int Eval()
{
JObject j = new JObject();
return x;
}
}
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
var references = new List<MetadataReference>();
//Load project libraries
//var assemblies = AppDomain.CurrentDomain
// .GetAssemblies()
// .Where(a => !a.IsDynamic)
// .Select(a => a.Location);
//foreach (var item in assemblies)
//{
// if (!item.Contains("xunit"))
// references.Add(MetadataReference.CreateFromFile(item));
//}
//or specify the libraries to load.
var coreDir = Directory.GetParent(typeof(Enumerable).GetTypeInfo().Assembly.Location);
var exeDir = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
references.Add(MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location));
references.Add(MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location));
references.Add(MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"));
references.Add(MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "System.Runtime.dll"));
if (File.Exists(exeDir + "\\Newtonsoft.Json.dll"))
references.Add(MetadataReference.CreateFromFile(exeDir + "\\Newtonsoft.Json.dll"));
else
throw new Exception("Missing newtonsoft DLL");
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
new[] { syntaxTree },
new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
},
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var memoryStream = new MemoryStream())
{
var result = compilation.Emit(memoryStream);
if (result.Success)
{
memoryStream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(memoryStream.ToArray());
Type testClassType = assembly.GetType("TestNamespace.TestClass");
var addResult = (int)testClassType.GetMethod("Add").Invoke(null, new object[] { 3, 4 });
Console.WriteLine(addResult);
}
else
{
Console.WriteLine("Failed to compile");
for (var i = 0; i < result.Diagnostics.Length; i++)
{
Console.WriteLine(result.Diagnostics[i].ToString());
}
}
}
}
static void Main(string[] args)
{
JObject j = null; //to make sure newtonsoft is included if loading current projects libraries
Example1();
}
}
}
使用系统;
使用System.IO;
使用System.Linq;
使用System.Collections.Generic;
运用系统反思;
使用Microsoft.CodeAnalysis;
使用Microsoft.CodeAnalysis.CSharp;
使用系统诊断;
使用Newtonsoft.Json.Linq;
命名空间测试脚本
{
班级计划
{
公共静态无效示例1()
{
var assemblyName=“UserScript”;
var code=@“命名空间用户脚本
{
使用制度;
使用System.IO;
使用System.Collections.Generic;
使用Newtonsoft.Json.Linq;
公共类运行脚本
{
私有常量int x=99;
公共内部评估()
{
JObject j=新的JObject();
返回x;
}
}
}";
SyntaxTree SyntaxTree=CSharpSyntaxTree.ParseText(代码);
var references=新列表();
//加载项目库
//var assemblies=AppDomain.CurrentDomain
//.getAssemblys()
//.其中(a=>!a.IsDynamic)
//.选择(a=>a.位置);
//foreach(程序集中的变量项)
//{
//如果(!item.Contains(“xunit”))
//添加(MetadataReference.CreateFromFile(项));
//}
//或者指定要加载的库。
var coreDir=Directory.GetParent(typeof(可枚举).GetTypeInfo().Assembly.Location);
var exeDir=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
Add(MetadataReference.CreateFromFile(typeof(Object).GetTypeInfo().Assembly.Location));
Add(MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location));
添加(MetadataReference.CreateFromFile(coreDir.FullName+Path.directoryseportorchar+mscorlib.dll));
添加(MetadataReference.CreateFromFile(coreDir.FullName+Path.directoryseportorchar+“System.Runtime.dll”);
if(File.Exists(exeDir+“\\Newtonsoft.Json.dll”))
添加(MetadataReference.CreateFromFile(exeDir+“\\Newtonsoft.Json.dll”);
其他的
抛出新异常(“缺少newtonsoft DLL”);
csharpcomilation=csharpcomilation.Create(
汇编名,
新[]{syntaxTree},
新MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object.Assembly.Location)
},
新的CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
使用(var memoryStream=new memoryStream())
{
var result=compilation.Emit(memoryStream);
如果(结果、成功)
{
memoryStream.Seek(0,SeekOrigin.Begin);
Assembly=Assembly.Load(memoryStream.ToArray());
类型testClassType=assembly.GetType(“TestNamespace.TestClass”);
var addResult=(int)testClassType.GetMethod(“Add”).Invoke(null,新对象[]{3,4});
Console.WriteLine(addResult);
}
其他的
{
Console.WriteLine(“编译失败”);
对于(变量i=0;i
如果您没有忘记使用您建立的参考
列表,那么您的代码应该可以正常工作
请参阅.NETFiddle()上的测试代码-我在那里使用了AppDomain
方法(您注释掉的方法)
编辑:以下是完整的工作代码,以防小提琴被删除:
public static void Main(string[] args)
{
var j = new JObject(); // ensure assembly is available
Example1();
}
public static void Example1()
{
var assemblyName = "UserScript";
var code = @"namespace UserScript {
using Newtonsoft.Json;
public class RunScript {
public static string Eval() {
return JsonConvert.SerializeObject(new int[] {1,2,3,4});
}
}
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
//Load project libraries
var references = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.IsDynamic)
.Select(a => a.Location)
.Where(s => !string.IsNullOrEmpty(s))
.Where(s => !s.Contains("xunit"))
.Select(s => MetadataReference.CreateFromFile(s))
.ToList()
;
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
new[] { syntaxTree },
references, //<-- you're missing this
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var memoryStream = new MemoryStream())
{
var result = compilation.Emit(memoryStream);
if (result.Success)
{
memoryStream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(memoryStream.ToArray());
var testClassType = assembly.GetType("UserScript.RunScript");
var invokeResult = (string)testClassType.GetMethod("Eval").Invoke(null, null);
Console.WriteLine(invokeResult);
}
else
{
Console.WriteLine("Failed to compile");
foreach (var diag in result.Diagnostics)
Console.WriteLine(diag);
}
}
}
publicstaticvoidmain(字符串[]args)
{
var j=new JObject();//确保程序集可用
例1();
}
公共静态无效示例1()
{
var assemblyName=“UserScript”;
var code=@“命名空间用户脚本{
使用Newtonsoft.Json;
公共类运行脚本{
公共静态字符串Eval(){
返回JsonConvert.SerializeObject(新的int[]{1,2,3,4});
}
}
}";
SyntaxTree SyntaxTree=CSharpSyntaxTree.ParseText(代码);
//加载项目库
var references=AppDomain.CurrentDomain
.getAssemblys()
.其中(a=>!a.IsDynamic)
.选择(a=>a.位置)
.Where(s=>!string.IsNullOrEmpty(s))
。其中(s=>!s.Contains(“xunit”))
.Select(s=>MetadataReference.CreateFromFile)
托利斯先生()
;
csharpcomilation=csharpcomilation.Create(
汇编名,
新[]{syntaxTree},
引用,//如果您没有忘记使用您建立的引用列表,那么您的代码应该可以正常工作
请参阅.NETFiddle()上的测试代码-我在那里使用了AppDomain
方法(您注释掉的方法)
编辑:这里
// Non-existent Type and Method...
Type testClassType = assembly.GetType("TestNamespace.TestClass");
var addResult = (int)testClassType.GetMethod("Add").Invoke(null, new object[] { 3, 4 });
public static void Main(string[] args)
{
var j = new JObject(); // ensure assembly is available
Example1();
}
public static void Example1()
{
var assemblyName = "UserScript";
var code = @"namespace UserScript {
using Newtonsoft.Json;
public class RunScript {
public static string Eval() {
return JsonConvert.SerializeObject(new int[] {1,2,3,4});
}
}
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
//Load project libraries
var references = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.IsDynamic)
.Select(a => a.Location)
.Where(s => !string.IsNullOrEmpty(s))
.Where(s => !s.Contains("xunit"))
.Select(s => MetadataReference.CreateFromFile(s))
.ToList()
;
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
new[] { syntaxTree },
references, //<-- you're missing this
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var memoryStream = new MemoryStream())
{
var result = compilation.Emit(memoryStream);
if (result.Success)
{
memoryStream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(memoryStream.ToArray());
var testClassType = assembly.GetType("UserScript.RunScript");
var invokeResult = (string)testClassType.GetMethod("Eval").Invoke(null, null);
Console.WriteLine(invokeResult);
}
else
{
Console.WriteLine("Failed to compile");
foreach (var diag in result.Diagnostics)
Console.WriteLine(diag);
}
}
}