using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Runtime;
using System.Runtime.CompilerServices;
namespace BPASmartClient.Compiler
{
///
/// C#编译器
///
public class CSharpConfig
{
#region 单例模式
public static CSharpConfig Instance = null;
public static CSharpConfig GetInstance()
{
if (Instance == null)
{
Instance = new CSharpConfig();
}
return Instance;
}
#endregion
public CSharpConfig()
{
}
public object RunCSharp(string code,object[] objValue,string error = "")
{
object strretu = string.Empty;
try
{
string funName = "main";
StringBuilder builder = new StringBuilder();
//builder.Append("using System;\n");
//builder.Append("using System.Linq;\n");
builder.Append("using Newtonsoft.Json;\n");
builder.Append("using Newtonsoft.Json.Linq;\n");
//builder.Append("using System.IO;\n");
//builder.Append("using System.Runtime;\n");
//builder.Append("using System.Text;\n");
builder.Append("using System.Collections.Generic;\n");
builder.Append("namespace YF \n{\n class CSharpConfigRun\n");
builder.Append(" {\n");
builder.Append(code);
builder.Append(" }\n}\n");
//1.添加要引用的程序集
string output = Path.GetTempFileName();
string assemblyName = Path.GetFileName(output);
var refPaths = new[] {
Assembly.GetExecutingAssembly().Location,
typeof(object).GetTypeInfo().Assembly.Location,
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.dll"),
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Collections.dll"),
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Threading.dll"),
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Newtonsoft.Json.dll"),
typeof(DynamicAttribute).GetTypeInfo().Assembly.Location,
};
MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
List refs = new List() {
MetadataReference.CreateFromFile (typeof (object).Assembly.Location),
MetadataReference.CreateFromFile (typeof (List).Assembly.Location),
MetadataReference.CreateFromFile (typeof (ASCIIEncoding).Assembly.Location),
MetadataReference.CreateFromFile (typeof (JsonConvert).Assembly.Location),
MetadataReference.CreateFromFile (typeof (JObject).Assembly.Location),
MetadataReference.CreateFromFile (typeof (Object).Assembly.Location),
MetadataReference.CreateFromFile (typeof (JContainer).Assembly.Location),
MetadataReference.CreateFromFile (typeof (JToken).Assembly.Location),
MetadataReference.CreateFromFile (typeof (Enumerable).Assembly.Location),
};
//2.需要编辑的C#代码
SyntaxTree tree = CSharpSyntaxTree.ParseText(builder.ToString());
//3.生成C#编译
var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
.WithOptions(new CSharpCompilationOptions(
Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary
,
usings: null,
optimizationLevel: OptimizationLevel.Debug, // TODO
checkOverflow: false, // TODO
allowUnsafe: true, // TODO
platform: Platform.AnyCpu,
warningLevel: 4,
xmlReferenceResolver: null
))
.AddReferences(references)
.AddSyntaxTrees(tree);
//var emitResult = compilation.Emit(output);
EmitResult emitResult;
byte[] dllBytes;
using (var stream = new MemoryStream())
{
emitResult = compilation.Emit(stream);
dllBytes = stream.ToArray();
}
if (emitResult.Success)
{
Assembly assembly = Assembly.Load(dllBytes);
var obj = assembly.CreateInstance("YF.CSharpConfigRun");
var method = obj.GetType().GetMethod("main",new Type[] { typeof(string) });
strretu = method.Invoke(obj,objValue);
}
//var providerOptions = new Dictionary();
//providerOptions.Add("CompilerVersion","v4.0");
//CSharpCodeProvider compiler = new CSharpCodeProvider(providerOptions);
//string output = Path.GetTempFileName();
//var cp = new CompilerParameters() { GenerateInMemory = true,OutputAssembly = output };
//cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
//cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
//cp.ReferencedAssemblies.Add("System.Core.dll");
//cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用
//cp.ReferencedAssemblies.Add("System.dll");
//cp.GenerateExecutable = false;
//cp.EmbeddedResources.Clear();
//cp.LinkedResources.Clear();
//cp.Win32Resource = null;
//cp.TreatWarningsAsErrors = false;
//cp.WarningLevel = 4;
//cp.TempFiles.KeepFiles = false;
//CompilerResults cr = compiler.CompileAssemblyFromSource(cp,builder.ToString());
// 1.ICodeComplier
// CSharpCodeProvider complier = new CSharpCodeProvider();
// // 2.CompilerParameters
// CompilerParameters cp = new CompilerParameters();
// cp.ReferencedAssemblies.Add("System.dll"); //添加引用
//// cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用
// cp.GenerateExecutable = false;
// cp.GenerateInMemory = true;
// // 3.CompilerResults
// CompilerResults cr = complier.CompileAssemblyFromSource(cp,builder.ToString());
//if (cr.Errors.HasErrors)
//{
// foreach (CompilerError err in cr.Errors)
// {
// error += err.ErrorText + "\r\n";
// }
//}
//else
//{
// // 通过反射,调用HelloWorld的实例
// Assembly objAssembly = cr.CompiledAssembly;
// object objClass = objAssembly.CreateInstance("CSharpConfigRun");
// MethodInfo objFun = objClass.GetType().GetMethod(funName);
// strretu = objFun.Invoke(objClass,objValue);
//}
}
catch (Exception ex)
{
error += ex.Message;
}
return strretu;
}
}
}