C# 动态编译执行

来源:互联网 发布:淘宝购物后怎么评价 编辑:程序博客网 时间:2024/05/17 22:43

 

动态编译执行Excuter.exe

源码:

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.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);                    }                    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();             }        }        # 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,

Test.cs:

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.txt    public 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();            }        }    }}



原创粉丝点击