C# 动态编译执行

 

动态编译执行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();
            }
        }

    }

}

 

 

 

 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值