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; } } }