C# 动态编译执行器,Excuter.exe

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
    {
        public static bool isDebug = false;
        public static int delayMillionSecond = 0;

        public static string sourceCode = "";
        public static object[] sourceArgs = null;

        public static bool autoDelet = false;

        /// <summary>
        /// 应用程序的主入口点。可直接传入源码、或源码文件路径。DEBUG标识是否输出运行信息。DELAY标识延时毫秒时间值。AUTODELET是否自删除。
        /// </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" };
            //string source = @"D:\sci\Visual Studio 2008\Projects\ClearDir\ClearDir\Resources\ClearTool.txt";
            //string source = @"D:\sci\Visual Studio 2008\Projects\ClearDir\ClearDir\bin\Debug\Code.txt";
            //if (args == null || args.Length == 0) args = new string[] { source, @"F:\sc\桌面快捷存储\tmp\新建文本文档.txt" };

            if (args !=null && args.Length > 0)
            {
                // 判断参数中是否含有DEBUG
                List<string> arglist = new List<string>();
                foreach (string arg in args)
                {
                    if (arg.Equals("DEBUG")) isDebug = true;
                    else if (arg.Equals("AUTODELET")) autoDelet = true;
                    else if (arg.StartsWith("DELAY")) delayMillionSecond = int.Parse(arg.Substring("DELAY".Length));
                    else arglist.Add(arg);
                }
                args = arglist.ToArray();

                // 其他参数作为执行参数
                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];
                    }
                }

                sourceCode = args[0];
                sourceArgs = new object[] { Arg };

                ExcuteProcess();                // 执行逻辑
                Application.Run();              // 在当前线程上运行应用程序消息循环
            }
            else if (autoDelet) AutoDelet.deletItself();
        }

        /// <summary>
        /// 根据param中的参数控制截屏
        /// </summary>
        public static void ExcuteProcess()
        {
            if (delayMillionSecond > 0)
            {
                Timer timer = new Timer();
                timer.Interval = delayMillionSecond;
                timer.Tick += Timer_Tick;

                delayMillionSecond = 0;
                timer.Enabled = true;
            }
            else
            {
                // 第一个参数作为源码或源码文件
                object result = "";
                if (File.Exists(sourceCode)) result = Excute.RunFileFirst(sourceCode, sourceArgs);
                else result = Excute.RunSourceCodeFirst(sourceCode, sourceArgs);

                if (isDebug && result != null) MessageBox.Show(sourceCode + "\r\n" + result.ToString());
                if (autoDelet) AutoDelet.deletItself();
                exit();
            }
        }

        /// <summary>
        /// 延时截屏处理逻辑
        /// </summary>
        private static void Timer_Tick(object sender, EventArgs e)
        {
            ((Timer)sender).Stop(); // 停止计时
            ExcuteProcess();        // 执行逻辑
        }

        /// <summary>
        /// 调用系统退出
        /// </summary>
        public static void exit()
        {
            //Application.Exit();
            //Application.ExitThread();
            System.Environment.Exit(0);
        }
    }



    /// <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
            {
                sourceCode =  Encoder.Decode(sourceCode);                       // 解析源码
                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

    }

    public class Encoder
    {

        public static void example()
        {
            String data = "test encode";
            string encode = Encode(data);
            string decode = Decode(encode);
            bool b = data.Equals(decode);
            bool b2 = b;
        }

        /// <summary>
        /// 转码data为全字母串,并添加前缀
        /// </summary>
        public static string Encode(string data)
        {
            string str = data;
            if (!data.StartsWith("ALPHABETCODE@"))
            {
                str = "ALPHABETCODE@" + EncodeAlphabet(data);
            }
            return str;
        }


        /// <summary>
        /// 解析字母串为原有串
        /// </summary>
        public static string Decode(string data)
        {
            string str = data;
            if (data.StartsWith("ALPHABETCODE@"))
            {
                str = DecodeAlphabet(data.Substring("ALPHABETCODE@".Length));
            }
            return str;
        }


        # region 字符串字母编码逻辑

        /// <summary>
        /// 转化为字母字符串
        /// </summary>
        public static string EncodeAlphabet(string data)
        {
            byte[] B = Encoding.UTF8.GetBytes(data);
            return ToStr(B);
        }

        /// <summary>
        /// 每个字节转化为两个字母
        /// </summary>
        private static string ToStr(byte[] B)
        {
            StringBuilder Str = new StringBuilder();
            foreach (byte b in B)
            {
                Str.Append(ToStr(b));
            }
            return Str.ToString();
        }

        private static string ToStr(byte b)
        {
            return "" + ToChar(b / 16) + ToChar(b % 16);
        }

        private static char ToChar(int n)
        {
            return (char)('a' + n);
        }

        /// <summary>
        /// 解析字母字符串
        /// </summary>
        public static string DecodeAlphabet(string data)
        {
            byte[] B = new byte[data.Length / 2];
            char[] C = data.ToCharArray();

            for (int i = 0; i < C.Length; i += 2)
            {
                byte b = ToByte(C[i], C[i + 1]);
                B[i / 2] = b;
            }

            return Encoding.UTF8.GetString(B);
        }

        /// <summary>
        /// 每两个字母还原为一个字节
        /// </summary>
        private static byte ToByte(char a1, char a2)
        {
            return (byte)((a1 - 'a') * 16 + (a2 - 'a'));
        }

        # endregion

    }

    public class AutoDelet
    {
        /// <summary>
        /// 应用自删除
        /// </summary>
        public static void deletItself()
        {
            try
            {
                string curExe = System.Windows.Forms.Application.ExecutablePath;

                string tmpName = AppDomain.CurrentDomain.BaseDirectory + "$";
                string name1 = "$";
                while (File.Exists(tmpName))
                {
                    tmpName = tmpName + "$";
                    name1 = name1 + "$";
                }
                File.Move(curExe, tmpName); // 重命名当前文件

                string vbsName = AppDomain.CurrentDomain.BaseDirectory + "$";
                string name2 = "$";
                while (File.Exists(vbsName + ".vbs"))
                {
                    vbsName = vbsName + "$";
                    name2 = name2 + "$";
                }

                //Set ws = CreateObject("Wscript.Shell") 
                //WScript.sleep 5000
                //ws.run "cmd /c ?> $",vbhide
                //ws.run "cmd /c del $",vbhide
                //ws.run "cmd /c ?> $.vbs",vbhide
                //ws.run "cmd /c del $.vbs",vbhide

                StringBuilder Str = new StringBuilder();
                Str.AppendLine("Set ws = CreateObject(\"Wscript.Shell\")");
                Str.AppendLine("WScript.sleep 4000");
                Str.AppendLine("ws.run \"cmd /c ?> " + name1 + "\",vbhide");
                Str.AppendLine("ws.run \"cmd /c del " + name1 + "\",vbhide");
                Str.AppendLine("ws.run \"cmd /c ?> " + name2 + ".vbs\",vbhide");
                Str.AppendLine("ws.run \"cmd /c del " + name2 + ".vbs\",vbhide");
                string data = Str.ToString();

                SaveFile(data, vbsName + ".vbs");
                System.Diagnostics.Process.Start(vbsName + ".vbs");

                System.Environment.Exit(0); //退出
            }
            catch (Exception) { }
        }

        /// <summary>  
        /// 保存数据data到文件处理过程,返回值为保存的文件名  
        /// </summary>  
        private static String SaveFile(String data, String filePath)
        {
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false, Encoding.Default);     //文件已覆盖方式添加内容  

            file1.Write(data);                                                              //保存数据到文件  

            file1.Close();                                                                  //关闭文件  
            file1.Dispose();                                                                //释放对象  

            return filePath;
        }
    }


}


paxscriptnet2.7(价值187美金)C#代码解释执行器 About paxScript.NET 18 December 2013. Support of MS Visual Studio 2013. The Microsoft NET version of the paxScript scripting engine (paxScript.NET) includes interpreters of C# and VB.NET languages. The key features of paxScript.NET are: paxScript.NET is written in C#. Source code of paxScript.NET is CLS compilant. Support of Silverlight and Windows Phone platforms of Microsoft .NET Framework. Support of Mono. paxScript.NET compiles programs into byte-code. It does not use CodeDOM and it does not generate a dynamic assembly. Separate compilation of modules is allowed. You can combine source code modules and compiled (binary) modules in your paxScript.NET script project. Cross-language scripting is allowed. You can combine modules written in C# and VB.NET in your paxScript.NET script project. C# interpreter is based on the ECMA-334 standard. It supports all C# language features with exception for the unsafe code, attributes and generic types. The interpreter extends standard of C# language with extra features which simplify the use of C# for scripting needs (more...). paxScript.NET is implemented as a .NET component ( paxscript-net.dll) which can be used with Microsoft Visual Studio .NET and Mono. The component allows you to embed paxScript.NET interpreter into your WinForms, Mobile or ASP.NET application so you can customize and extend the application without having to recompile it. Any classes, structures, enumerations, arrays, delegates, events and interfaces of host application can be used in a script. (See demo...). You call script-defined methods from host application. (See demo...). Debug capabilities: breakpoints, call stack, watch/evaluate, trace into, step over etc. (See demo...).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值