C# 从源码生成EXE

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SciTools
{
    /// 
    /// EXE文件工具类
    /// 
    public class ExeTool
    {
        # region 动态编译源码

        /// 
        /// 解析并编译源码sourceCode,生成EXE
        /// 
        public static void CompileExe(string sourceCode, string exeFile)
        {
            try
            {
                string[] assemblies = getUsing(sourceCode).ToArray();   // 获取引用程序集
                string result = (string) Compile(sourceCode, exeFile, assemblies);        // 编译源码
                if (!result.Equals("编译通过")) MessageBox.Show(result);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }


        /// 
        /// 动态编译执行
        /// 
        /// 源码
        /// 引用程序集
        static object Compile(string sourceCode, string exeFile, string[] assemblies = null)
        {
            try
            {
                // 设置编译参数 System.Xml.dll
                CompilerParameters param = new CompilerParameters();
                param.GenerateExecutable = true;
                param.OutputAssembly = exeFile;
                //param.GenerateInMemory = 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.ToString());
                    }
                    return str.ToString();
                }
                else
                {
                    // 编译通过:
                    return "编译通过";
                }
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }

        # endregion


        # region 相关功能函数

        ///// 
        ///// 获取文件中的数据,自动判定编码格式
        ///// 
        //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;
        //}

        ///// 
        ///// 获取第一个公用方法
        ///// 
        ///// 
        ///// 
        //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;
        //}

        ///// 
        ///// 判断指定的方法是否为静态方法
        ///// 
        ///// 
        //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;
        //}

        /// 
        /// 获取应用的程序集信息
        /// 
        private static List getUsing(string sourceCode)
        {
            String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
            List usings = new List();
            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;
        }

        /// 
        /// 检测添加较短长度的Assembly名称
        /// 
        private static void CheckAddAssembly(List 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
    }
}

 

你可能感兴趣的:(C#,生成EXE)