1. using Microsoft.CSharp;
    2. using System;
    3. using System.CodeDom.Compiler;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6. using System.Text;
    7. using System.Threading.Tasks;
    8. using System.Windows.Forms;
    9. namespace SciTools
    10. {
    11. /// <summary>
    12. /// EXE文件工具类
    13. /// </summary>
    14. public class ExeTool
    15. {
    16. # region 动态编译源码
    17. /// <summary>
    18. /// 解析并编译源码sourceCode,生成EXE
    19. /// </summary>
    20. public static void CompileExe(string sourceCode, string exeFile)
    21. {
    22. try
    23. {
    24. string[] assemblies = getUsing(sourceCode).ToArray(); // 获取引用程序集
    25. string result = (string) Compile(sourceCode, exeFile, assemblies); // 编译源码
    26. if (!result.Equals("编译通过")) MessageBox.Show(result);
    27. }
    28. catch (Exception ex)
    29. {
    30. MessageBox.Show(ex.ToString());
    31. }
    32. }
    33. /// <summary>
    34. /// 动态编译执行
    35. /// </summary>
    36. /// <param name="sourceCode">源码</param>
    37. /// <param name="assemblies">引用程序集</param>
    38. static object Compile(string sourceCode, string exeFile, string[] assemblies = null)
    39. {
    40. try
    41. {
    42. // 设置编译参数 System.Xml.dll
    43. CompilerParameters param = new CompilerParameters();
    44. param.GenerateExecutable = true;
    45. param.OutputAssembly = exeFile;
    46. //param.GenerateInMemory = false;
    47. //param.GenerateInMemory = true;
    48. // 添加常用的默认程序集
    49. param.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
    50. param.ReferencedAssemblies.Add("mscorlib.dll");
    51. param.ReferencedAssemblies.Add("System.dll");
    52. param.ReferencedAssemblies.Add("System.Core.dll");
    53. param.ReferencedAssemblies.Add("System.Data.dll");
    54. param.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
    55. param.ReferencedAssemblies.Add("System.Drawing.dll");
    56. param.ReferencedAssemblies.Add("System.Windows.Forms.dll");
    57. param.ReferencedAssemblies.Add("System.Xml.dll");
    58. param.ReferencedAssemblies.Add("System.Xml.Linq.dll");
    59. if (assemblies != null)
    60. {
    61. foreach (string name in assemblies)
    62. {
    63. string assembly = name + ".dll";
    64. if (!param.ReferencedAssemblies.Contains(assembly))
    65. {
    66. param.ReferencedAssemblies.Add(assembly);
    67. }
    68. }
    69. }
    70. // 动态编译字符串代码
    71. CompilerResults result = new CSharpCodeProvider().CompileAssemblyFromSource(param, sourceCode);
    72. if (result.Errors.HasErrors)
    73. {
    74. // 编译出错:
    75. StringBuilder str = new StringBuilder();
    76. foreach (CompilerError err in result.Errors)
    77. {
    78. str.AppendLine(err.ToString());
    79. }
    80. return str.ToString();
    81. }
    82. else
    83. {
    84. // 编译通过:
    85. return "编译通过";
    86. }
    87. }
    88. catch (Exception ex)
    89. {
    90. return ex.ToString();
    91. }
    92. }
    93. # endregion
    94. # region 相关功能函数
    95. ///// <summary>
    96. ///// 获取文件中的数据,自动判定编码格式
    97. ///// </summary>
    98. //private static string fileToString(String filePath)
    99. //{
    100. // string str = "";
    101. // //获取文件内容
    102. // if (File.Exists(filePath))
    103. // {
    104. // StreamReader file1;
    105. // file1 = new StreamReader(filePath, Encoding.UTF8); // 读取文件中的数据
    106. // str = file1.ReadToEnd(); // 读取文件中的全部数据
    107. // file1.Close();
    108. // file1.Dispose();
    109. // }
    110. // return str;
    111. //}
    112. ///// <summary>
    113. ///// 获取第一个公用方法
    114. ///// </summary>
    115. ///// <param name="sourceCode"></param>
    116. ///// <returns></returns>
    117. //private static string getFirstPublicMethod(string sourceCode)
    118. //{
    119. // string methodName = "";
    120. // String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
    121. // foreach (string iteam in lines)
    122. // {
    123. // string line = iteam.Trim();
    124. // if (line.StartsWith("public ") && line.Contains("(") && line.Contains(")"))
    125. // {
    126. // methodName = line.Substring(0, line.IndexOf("("));
    127. // methodName = methodName.Substring(methodName.LastIndexOf(" ") + 1);
    128. // break;
    129. // }
    130. // }
    131. // return methodName;
    132. //}
    133. ///// <summary>
    134. ///// 判断指定的方法是否为静态方法
    135. ///// </summary>
    136. ///// <returns></returns>
    137. //private static bool isPublicStaticMethod(string sourceCode, string methodName)
    138. //{
    139. // bool isStatic = false;
    140. // String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
    141. // foreach (string iteam in lines)
    142. // {
    143. // string line = iteam.Trim();
    144. // if (line.StartsWith("public ") && line.Contains(" " + methodName) && line.Contains("(") && line.Contains(")") && line.Contains("static"))
    145. // {
    146. // isStatic = true;
    147. // }
    148. // }
    149. // return isStatic;
    150. //}
    151. /// <summary>
    152. /// 获取应用的程序集信息
    153. /// </summary>
    154. private static List<string> getUsing(string sourceCode)
    155. {
    156. String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
    157. List<string> usings = new List<string>();
    158. foreach (string iteam in lines)
    159. {
    160. string line = iteam.Trim();
    161. if (line.StartsWith("using ") && line.EndsWith(";"))
    162. {
    163. string usingAssembley = line.TrimEnd(';').Substring("using ".Length);
    164. CheckAddAssembly(usings, usingAssembley);
    165. }
    166. }
    167. return usings;
    168. }
    169. /// <summary>
    170. /// 检测添加较短长度的Assembly名称
    171. /// </summary>
    172. private static void CheckAddAssembly(List<string> usings, string usingAssembley)
    173. {
    174. if (usings.Contains(usingAssembley)) return;
    175. for (int i = 0; i < usings.Count; i++)
    176. {
    177. string name = usings[i];
    178. if (usingAssembley.StartsWith(name + ".")) return;
    179. else if (name.StartsWith(usingAssembley + "."))
    180. {
    181. usings[i] = usingAssembley;
    182. }
    183. }
    184. usings.Add(usingAssembley);
    185. }
    186. # endregion
    187. }
    188. }