|
- 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
- {
- /// <summary>
- /// C#编译器
- /// </summary>
- 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<MetadataReference> refs = new List<MetadataReference>() {
- MetadataReference.CreateFromFile (typeof (object).Assembly.Location),
- MetadataReference.CreateFromFile (typeof (List<int>).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<string,string>();
- //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;
- }
- }
- }
|