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;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[] { @"F:\sc\桌面快捷存储\tmp\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.dllCompilerParameters 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);}return str.ToString();}else{// 编译通过:Assembly assembly = result.CompiledAssembly; // 获取已编译通过的程序集if (classFullName == null || classFullName.Equals("")) // 若未指定,则获取程序集第一个类路径名{classFullName = assembly.GetTypes()[0].FullName;}if (isStaticMethod){// 调用程序集的静态方法: Type.InvokeMemberType 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.Invokeobject obj = assembly.CreateInstance(classFullName); // 创建一个类实例对象MethodInfo method = obj.GetType().GetMethod(methodName);// 获取对象的对应方法object tmp = method.Invoke(obj, args); // 调用对象的方法return tmp;}}}catch (Exception ex){return ex.ToString();}}# 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}}
示例1:
using System;using System.Collections.Generic;using System.Text;using System.Windows.Forms;namespace Demo{class Test{public static void Demo(){MessageBox.Show("动态编译执行示例!");}}}
示例2,
可用于动态执行的示例代码:ClearTool.cs(清除逻辑中指定的文件,拖动此文件至Excuter.exe可执行设定逻辑)
using System;using System.Collections.Generic;using System.IO;using System.Text;using System.Threading.Tasks;namespace ClearDir2{// cmd延时执行//choice /t 2 /d y /n >nul//echo del>%~dp0test.txt//pause del %~dp0test.txtpublic class ClearTool{/// <summary>/// 清空目录或文件/// </summary>public static void Default(){string filePath = @"F:\sc\桌面快捷存储\tmp\dat.txt";ClearDelet(filePath);}/// <summary>/// 清空目录或文件/// </summary>public static void ClearDelet(string path){if (File.Exists(path)) ClearDeletFile(path);if (Directory.Exists(path)) ClearDeletDirectory(path);}/// <summary>/// 先清空目录中的所有文件和子目录内容,再删除当前目录/// </summary>public static void ClearDeletDirectory(string dir){if (Directory.Exists(dir)){// 清除目录下的所有文件foreach (String iteam in Directory.GetFiles(dir)){ClearDeletFile(iteam);}// 清除目录下的所有子目录foreach (String iteam in Directory.GetDirectories(dir)){ClearDeletDirectory(iteam);}String newName = System.IO.Directory.GetParent(dir).FullName + "\\$";while (File.Exists(newName)) newName += "$";// 清除当前目录Directory.Move(dir, newName); // 重命名当前目录,清除目录名信息Directory.Delete(newName); // 清除当前目录}}/// <summary>/// 先清空文件内容,再删除/// </summary>public static void ClearDeletFile(string file){ClearFile(file); // 清空文件内容if (File.Exists(file)){String newName = System.IO.Directory.GetParent(file).FullName + "\\$";while (File.Exists(newName)) newName += "$";File.Move(file, newName); // 重命名文件,清除文件名称信息File.Delete(newName); // 删除文件}}/// <summary>/// 清空文件内容/// </summary>public static void ClearFile(string file){if (File.Exists(file)){int SIZE = 1024 * 10240;byte[] array = new byte[SIZE];array.Initialize();FileStream s = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, SIZE, FileOptions.RandomAccess);// 清空原有文件内容while (s.Position + SIZE <= s.Length - 1){s.Write(array, 0, SIZE);}int reminds = (int)(s.Length - s.Position);if (reminds > 0) s.Write(array, 0, reminds);// 清除文件长度信息s.SetLength(0);s.Close();}}}}
