編譯+執行代碼如下
//using System; //namespace DynamicCode //{ // class Program // { // static void Main(string[] args) // { // Console.WriteLine("Hello World!"); // } // } //} using System; using System.Collections.Generic; //using System.Windows.Forms; using System.Threading.Tasks; using System.IO; using System.Reflection; using System.Text; using System.CodeDom.Compiler; using Microsoft.CSharp; using static System.Net.Mime.MediaTypeNames; namespace Excuter { static class Program { /// <summary> /// 應用程序的主入口點。 /// </summary> [STAThread] static void Main(string[] args) { //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); if (args == null || args.Length == 0) args = new string[] { @"D:\coding\JahwaPLM\test.cs" }; if (args != null && args.Length > 0) { // 其他參數作為執行參數 string[] Arg = null; if (args.Length > 1) { Arg = new string[args.Length - 1]; for (int i = 1; i < args.Length; i++) { Arg[i - 1] = args[i]; } } // 第一個參數作為源碼或源碼文件 if (File.Exists(args[0])) Excute.RunFileFirst(args[0], Arg); else Excute.RunSourceCodeFirst(args[0], Arg); } } } /// <summary> /// 動態編譯執行 /// </summary> public class Excute { #region 動態編譯源碼並執行 /// <summary> /// 解析並編譯執行源碼文件sourceFile,第一個類的首個公用或靜態方法 /// </summary> public static object RunFileFirst(string sourceFile, object[] args = null) { try { string sourceCode = fileToString(sourceFile); return RunSourceCodeFirst(sourceCode, args); } catch (Exception ex) { return ex.ToString(); } } /// <summary> /// 解析並編譯執行sourceCode,第一個類的首個公用或靜態方法 /// </summary> public static object RunSourceCodeFirst(string sourceCode, object[] args = null) { try { string[] assemblies = getUsing(sourceCode).ToArray(); // 獲取引用程序集 string methodName = getFirstPublicMethod(sourceCode); // 獲取方法名 bool isStatic = isPublicStaticMethod(sourceCode, methodName); // 判斷是否為靜態方法 return Run(sourceCode, "", methodName, args, isStatic, assemblies); // 執行 } catch (Exception ex) { return ex.ToString(); } } /// <summary> /// 動態編譯執行 /// </summary> /// <param name="sourceCode">源碼</param> /// <param name="classFullName">命名空間.類</param> /// <param name="methodName">方法名</param> /// <param name="args">方法參數</param> /// <param name="assemblies">引用程序集</param> /// <param name="isStaticMethod">是否為靜態方法</param> static object Run(string sourceCode, string classFullName, string methodName, object[] args = null, bool isStaticMethod = false, string[] assemblies = null) { try { // 設置編譯參數 System.Xml.dll CompilerParameters param = new CompilerParameters(); param.GenerateExecutable = false; param.GenerateInMemory = true; // 添加常用的默認程序集 param.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); param.ReferencedAssemblies.Add("mscorlib.dll"); param.ReferencedAssemblies.Add("System.dll"); param.ReferencedAssemblies.Add("System.Core.dll"); param.ReferencedAssemblies.Add("System.Data.dll"); param.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll"); param.ReferencedAssemblies.Add("System.Drawing.dll"); param.ReferencedAssemblies.Add("System.Windows.Forms.dll"); param.ReferencedAssemblies.Add("System.Xml.dll"); param.ReferencedAssemblies.Add("System.Xml.Linq.dll"); if (assemblies != null) { foreach (string name in assemblies) { string assembly = name + ".dll"; if (!param.ReferencedAssemblies.Contains(assembly)) { param.ReferencedAssemblies.Add(assembly); } } } // 動態編譯字符串代碼 CompilerResults result = new CSharpCodeProvider().CompileAssemblyFromSource(param, sourceCode); if (result.Errors.HasErrors) { // 編譯出錯: StringBuilder str = new StringBuilder(); foreach (CompilerError err in result.Errors) { str.AppendLine(err.ErrorText); } Console.WriteLine(str.ToString()); return str.ToString(); } else { // 編譯通過: Assembly assembly = result.CompiledAssembly; // 獲取已編譯通過的程序集 if (classFullName == null || classFullName.Equals("")) // 若未指定,則獲取程序集第一個類路徑名 { classFullName = assembly.GetTypes()[0].FullName; } if (isStaticMethod) { // 調用程序集的靜態方法: Type.InvokeMember Type type = assembly.GetType(classFullName, true, true); //object[] arg = new object[] { "參數1", "參數2" }; object tmp = type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args); return tmp; } else { // 調用程序集類實例方法: method.Invoke object obj = assembly.CreateInstance(classFullName); // 創建一個類實例對象 MethodInfo method = obj.GetType().GetMethod(methodName);// 獲取對象的對應方法 object tmp = method.Invoke(obj, args); // 調用對象的方法 return tmp; } } } catch (Exception ex) { return ex.ToString(); } Console.WriteLine("RUN OK"); } #endregion #region 相關功能函數 /// <summary> /// 獲取文件中的數據,自動判定編碼格式 /// </summary> private static string fileToString(String filePath) { string str = ""; //獲取文件內容 if (File.Exists(filePath)) { StreamReader file1; file1 = new StreamReader(filePath, Encoding.UTF8); // 讀取文件中的數據 str = file1.ReadToEnd(); // 讀取文件中的全部數據 file1.Close(); file1.Dispose(); } return str; } /// <summary> /// 獲取第一個公用方法 /// </summary> /// <param name="sourceCode"></param> /// <returns></returns> private static string getFirstPublicMethod(string sourceCode) { string methodName = ""; String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n'); foreach (string iteam in lines) { string line = iteam.Trim(); if (line.StartsWith("public ") && line.Contains("(") && line.Contains(")")) { methodName = line.Substring(0, line.IndexOf("(")); methodName = methodName.Substring(methodName.LastIndexOf(" ") + 1); break; } } return methodName; } /// <summary> /// 判斷指定的方法是否為靜態方法 /// </summary> /// <returns></returns> private static bool isPublicStaticMethod(string sourceCode, string methodName) { bool isStatic = false; String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n'); foreach (string iteam in lines) { string line = iteam.Trim(); if (line.StartsWith("public ") && line.Contains(" " + methodName) && line.Contains("(") && line.Contains(")") && line.Contains("static")) { isStatic = true; } } return isStatic; } /// <summary> /// 獲取應用的程序集信息 /// </summary> private static List<string> getUsing(string sourceCode) { String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n'); List<string> usings = new List<string>(); foreach (string iteam in lines) { string line = iteam.Trim(); if (line.StartsWith("using ") && line.EndsWith(";")) { string usingAssembley = line.TrimEnd(';').Substring("using ".Length); CheckAddAssembly(usings, usingAssembley); } } return usings; } /// <summary> /// 檢測添加較短長度的Assembly名稱 /// </summary> private static void CheckAddAssembly(List<string> usings, string usingAssembley) { if (usings.Contains(usingAssembley)) return; for (int i = 0; i < usings.Count; i++) { string name = usings[i]; if (usingAssembley.StartsWith(name + ".")) return; else if (name.StartsWith(usingAssembley + ".")) { usings[i] = usingAssembley; } } usings.Add(usingAssembley); } #endregion } }
測試代碼 將需的第三方庫copy到執行器目錄Newtonsoft.Json
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Excuter { public class pp { public static void run() { Task.Run(()=>{ Console.WriteLine("-----run ok"); //var b = SqlHelper.GetProjectType(11); //Console.WriteLine(JsonConvert.SerializeObject(b)); }); Console.WriteLine("-----"); //var a = SqlHelper.GetProjectType(11); //Console.WriteLine(JsonConvert.SerializeObject(a)); Console.ReadKey(); } } public class SqlHelper { public static string ConnString = @"data source=172.24.106.66;initial catalog=DXCCosmetics310;user id=sa;password=123456;max pool size=200;Pooling=true;"; //ConfigurationManager.ConnectionStrings["sql"].ConnectionString; // @"server=6;uid=sa;pwd=;database=;";// //初始化SqlCommand對象 public static void InitializeCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] paras) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = cmdType; if (paras != null) foreach (SqlParameter item in paras) { cmd.Parameters.Add(item); } } //查詢數據,返回相應的數據表 public static DataTable GetDataTable(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras) { SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) { InitializeCommand(cmd, conn, null, cmdType, cmdText, paras); using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { DataTable dt = new DataTable(); adapter.Fill(dt); cmd.Parameters.Clear(); return dt; } } } //查詢單個數據,返回第一列第一行的數據 public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras) { SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) { InitializeCommand(cmd, conn, null, cmdType, cmdText, paras); object obj = cmd.ExecuteScalar(); cmd.Parameters.Clear(); return obj; } } public static object GetProjectType(int projectCode) { //首先定義用於查詢的SQL腳本 string cmdText = @"SELECT top 10 * FROM ;"; //使用SqlHelper操作類來讀取表數據 //定義一個用於存儲讀取過來的表數據DataTable對象 try { DataTable dt = SqlHelper.GetDataTable(SqlHelper.ConnString, CommandType.Text, cmdText); return dt; //var dt = SqlHelper.ExecuteScalar(SqlHelper.ConnString, CommandType.Text, cmdText); //return dt; } catch (Exception ex) { LogHelper.Debug(JsonConvert.SerializeObject(ex)); } return null; } } /// <summary> /// 打印Log /// </summary> public class LogHelper { static bool LogOff = false; public static string GetDirPath() { var Dic = AppDomain.CurrentDomain.BaseDirectory.Split('\\').ToList(); if (Dic.Count <= 3) { return AppDomain.CurrentDomain.BaseDirectory + "\\logs"; } var Dics = Dic.Take(Dic.Count - 3).ToArray(); string path = string.Join("\\", Dics) + "\\logs"; return path; } //在網站根目錄下創建日志目錄(bin文件夾→debug文件夾→logs文件夾) public static string path = GetDirPath();// @"..\..\logs\";// //死鎖 public static object loglock = new object(); public static void Debug(string content) { WriteLog("DEBUG", content); } public static void Info(string content) { WriteLog("INFO", content); } public static void Error(string content) { WriteLog("ERROR", content); } protected static void WriteLog(string type, string content) { if (LogOff) { return; } lock (loglock) { if (!Directory.Exists(path))//如果日志目錄不存在就創建 { Directory.CreateDirectory(path); } string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");//獲取當前系統時間 string filename = path + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";//用日期對日志文件命名 //創建或打開日志文件,向日志文件末尾追加記錄 StreamWriter mySw = File.AppendText(filename); //向日志文件寫入內容 string write_content = time + " " + type + ": " + content; mySw.WriteLine(write_content); //關閉日志文件 mySw.Close(); } } } }