You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.5 KiB
108 lines
4.5 KiB
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.Emit;
|
|
using Microsoft.CodeAnalysis;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
namespace Shentun.Peis.DiagnosisFunctions
|
|
{
|
|
public class CodeBuilder
|
|
{
|
|
private static List<MetadataReference> _references = new List<MetadataReference>();
|
|
/// <summary>
|
|
/// 编译前的初始化,只需要一次
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
static CodeBuilder()
|
|
{
|
|
_references = new List<MetadataReference>();
|
|
|
|
// 元数据引用
|
|
if (_references == null || _references.Count == 0)
|
|
{
|
|
_references = new List<MetadataReference>()
|
|
{
|
|
MetadataReference.CreateFromFile(typeof(System.Uri).Assembly.Location),
|
|
MetadataReference.CreateFromFile(typeof(System.Linq.Enumerable).Assembly.Location),
|
|
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
|
|
MetadataReference.CreateFromFile(typeof(System.IO.File).Assembly.Location),
|
|
MetadataReference.CreateFromFile(Assembly.Load("System.Runtime").Location),
|
|
MetadataReference.CreateFromFile(Assembly.Load("System.Collections").Location),
|
|
MetadataReference.CreateFromFile(Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory+"Shentun.Peis.Application.dll").Location),
|
|
};
|
|
}
|
|
//Assembly as1 = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "mscorlib.dll");
|
|
//MetadataReference metadataReference = _references.Find((o => o.Display.Contains("mscorlib.dll")));
|
|
//if (_references.Find((o => o.Display.Contains("mscorlib.dll"))) == null)
|
|
//{
|
|
// _references.Add(MetadataReference.CreateFromFile(as1.Location));
|
|
//}
|
|
}
|
|
|
|
//public CodeBuilder()
|
|
//{
|
|
//}
|
|
//public Assembly CreateCode(string code)
|
|
//{
|
|
// //var domain = new NatashaDomain("key");
|
|
// //var domain = DomainManagement.Random();
|
|
// NatashaManagement.Preheating();
|
|
// Path.GetRandomFileName();
|
|
// using (DomainManagement.Create("myDomain").CreateScope())
|
|
// {
|
|
// AssemblyCSharpBuilder builder = new AssemblyCSharpBuilder();
|
|
// builder.Add(code);
|
|
// var func = builder.GetDelegateFromShortName<Func<string>>("Test", "GetName");
|
|
// }
|
|
|
|
// return myAssembly;
|
|
//}
|
|
public Assembly GenerateAssemblyFromCode(string code)
|
|
{
|
|
Assembly assembly = null;
|
|
|
|
// 丛代码中转换表达式树
|
|
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
|
|
// 随机程序集名称
|
|
//string assemblyName = Path.GetRandomFileName();
|
|
var assemblyName = "_" + Guid.NewGuid().ToString("D");
|
|
//assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
|
|
//assemblyName = "Shentun.Peis.Application";
|
|
var syntaxTrees = new SyntaxTree[] { syntaxTree };
|
|
// 引用
|
|
var references = _references;// referencedAssemblies.Select(x => MetadataReference.CreateFromFile(x.Location));
|
|
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
|
|
|
|
// 创建编译对象
|
|
CSharpCompilation compilation = CSharpCompilation.Create(assemblyName, syntaxTrees, references, options);
|
|
|
|
using (var ms = new MemoryStream())
|
|
{
|
|
// 将编译好的IL代码放入内存流
|
|
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.Load(ms.ToArray());
|
|
}
|
|
}
|
|
return assembly;
|
|
}
|
|
}
|
|
|
|
}
|