终端一体化运控平台
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.
 
 
 

182 lines
8.1 KiB

  1. using Microsoft.CodeAnalysis;
  2. using Microsoft.CodeAnalysis.CSharp;
  3. using Microsoft.CodeAnalysis.Emit;
  4. using Microsoft.CSharp;
  5. using System;
  6. using System.CodeDom.Compiler;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Reflection;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using Newtonsoft.Json;
  13. using Newtonsoft.Json.Linq;
  14. using System.Runtime;
  15. using System.Runtime.CompilerServices;
  16. namespace BPASmartClient.Compiler
  17. {
  18. /// <summary>
  19. /// C#编译器
  20. /// </summary>
  21. public class CSharpConfig
  22. {
  23. #region 单例模式
  24. public static CSharpConfig Instance = null;
  25. public static CSharpConfig GetInstance()
  26. {
  27. if (Instance == null)
  28. {
  29. Instance = new CSharpConfig();
  30. }
  31. return Instance;
  32. }
  33. #endregion
  34. public CSharpConfig()
  35. {
  36. }
  37. public object RunCSharp(string code,object[] objValue,string error = "")
  38. {
  39. object strretu = string.Empty;
  40. try
  41. {
  42. string funName = "main";
  43. StringBuilder builder = new StringBuilder();
  44. //builder.Append("using System;\n");
  45. //builder.Append("using System.Linq;\n");
  46. builder.Append("using Newtonsoft.Json;\n");
  47. builder.Append("using Newtonsoft.Json.Linq;\n");
  48. //builder.Append("using System.IO;\n");
  49. //builder.Append("using System.Runtime;\n");
  50. //builder.Append("using System.Text;\n");
  51. builder.Append("using System.Collections.Generic;\n");
  52. builder.Append("namespace YF \n{\n class CSharpConfigRun\n");
  53. builder.Append(" {\n");
  54. builder.Append(code);
  55. builder.Append(" }\n}\n");
  56. //1.添加要引用的程序集
  57. string output = Path.GetTempFileName();
  58. string assemblyName = Path.GetFileName(output);
  59. var refPaths = new[] {
  60. Assembly.GetExecutingAssembly().Location,
  61. typeof(object).GetTypeInfo().Assembly.Location,
  62. Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.dll"),
  63. Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Collections.dll"),
  64. Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Threading.dll"),
  65. Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
  66. Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Newtonsoft.Json.dll"),
  67. typeof(DynamicAttribute).GetTypeInfo().Assembly.Location,
  68. };
  69. MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
  70. List<MetadataReference> refs = new List<MetadataReference>() {
  71. MetadataReference.CreateFromFile (typeof (object).Assembly.Location),
  72. MetadataReference.CreateFromFile (typeof (List<int>).Assembly.Location),
  73. MetadataReference.CreateFromFile (typeof (ASCIIEncoding).Assembly.Location),
  74. MetadataReference.CreateFromFile (typeof (JsonConvert).Assembly.Location),
  75. MetadataReference.CreateFromFile (typeof (JObject).Assembly.Location),
  76. MetadataReference.CreateFromFile (typeof (Object).Assembly.Location),
  77. MetadataReference.CreateFromFile (typeof (JContainer).Assembly.Location),
  78. MetadataReference.CreateFromFile (typeof (JToken).Assembly.Location),
  79. MetadataReference.CreateFromFile (typeof (Enumerable).Assembly.Location),
  80. };
  81. //2.需要编辑的C#代码
  82. SyntaxTree tree = CSharpSyntaxTree.ParseText(builder.ToString());
  83. //3.生成C#编译
  84. var compilation = CSharpCompilation.Create(Guid.NewGuid().ToString() + ".dll")
  85. .WithOptions(new CSharpCompilationOptions(
  86. Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary
  87. ,
  88. usings: null,
  89. optimizationLevel: OptimizationLevel.Debug, // TODO
  90. checkOverflow: false, // TODO
  91. allowUnsafe: true, // TODO
  92. platform: Platform.AnyCpu,
  93. warningLevel: 4,
  94. xmlReferenceResolver: null
  95. ))
  96. .AddReferences(references)
  97. .AddSyntaxTrees(tree);
  98. //var emitResult = compilation.Emit(output);
  99. EmitResult emitResult;
  100. byte[] dllBytes;
  101. using (var stream = new MemoryStream())
  102. {
  103. emitResult = compilation.Emit(stream);
  104. dllBytes = stream.ToArray();
  105. }
  106. if (emitResult.Success)
  107. {
  108. Assembly assembly = Assembly.Load(dllBytes);
  109. var obj = assembly.CreateInstance("YF.CSharpConfigRun");
  110. var method = obj.GetType().GetMethod("main",new Type[] { typeof(string) });
  111. strretu = method.Invoke(obj,objValue);
  112. }
  113. //var providerOptions = new Dictionary<string,string>();
  114. //providerOptions.Add("CompilerVersion","v4.0");
  115. //CSharpCodeProvider compiler = new CSharpCodeProvider(providerOptions);
  116. //string output = Path.GetTempFileName();
  117. //var cp = new CompilerParameters() { GenerateInMemory = true,OutputAssembly = output };
  118. //cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
  119. //cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
  120. //cp.ReferencedAssemblies.Add("System.Core.dll");
  121. //cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用
  122. //cp.ReferencedAssemblies.Add("System.dll");
  123. //cp.GenerateExecutable = false;
  124. //cp.EmbeddedResources.Clear();
  125. //cp.LinkedResources.Clear();
  126. //cp.Win32Resource = null;
  127. //cp.TreatWarningsAsErrors = false;
  128. //cp.WarningLevel = 4;
  129. //cp.TempFiles.KeepFiles = false;
  130. //CompilerResults cr = compiler.CompileAssemblyFromSource(cp,builder.ToString());
  131. // 1.ICodeComplier
  132. // CSharpCodeProvider complier = new CSharpCodeProvider();
  133. // // 2.CompilerParameters
  134. // CompilerParameters cp = new CompilerParameters();
  135. // cp.ReferencedAssemblies.Add("System.dll"); //添加引用
  136. //// cp.ReferencedAssemblies.Add("Newtonsoft.Json.dll"); //添加引用
  137. // cp.GenerateExecutable = false;
  138. // cp.GenerateInMemory = true;
  139. // // 3.CompilerResults
  140. // CompilerResults cr = complier.CompileAssemblyFromSource(cp,builder.ToString());
  141. //if (cr.Errors.HasErrors)
  142. //{
  143. // foreach (CompilerError err in cr.Errors)
  144. // {
  145. // error += err.ErrorText + "\r\n";
  146. // }
  147. //}
  148. //else
  149. //{
  150. // // 通过反射,调用HelloWorld的实例
  151. // Assembly objAssembly = cr.CompiledAssembly;
  152. // object objClass = objAssembly.CreateInstance("CSharpConfigRun");
  153. // MethodInfo objFun = objClass.GetType().GetMethod(funName);
  154. // strretu = objFun.Invoke(objClass,objValue);
  155. //}
  156. }
  157. catch (Exception ex)
  158. {
  159. error += ex.Message;
  160. }
  161. return strretu;
  162. }
  163. }
  164. }