zoukankan      html  css  js  c++  java
  • 动态编译

    AssemblyInfo.cs

              AppDomain.CurrentDomain.AppendPrivatePath("");
               AppDomain.CurrentDomain.SetupInformation.PrivateBinPath="";

    /keyfile:vv.snk

    AppDomainSetup.ConfiguraitonFile属性就是指的这个

    <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="Castle;Core;Module;UI;Misc;"/>
      </assemblyBinding>
    </runtime>
    static Program()
    
    {
    
        AppDomain.CurrentDomain.SetData("PRIVATE_BINPATH", "Castle;Core;Module;UI;Misc;");
    
        AppDomain.CurrentDomain.SetData("BINPATH_PROBE_ONLY", "Castle;Core;Module;UI;Misc;");
    
        var m = typeof(AppDomainSetup).GetMethod("UpdateContextProperty", BindingFlags.NonPublic | BindingFlags.Static);
    
        var funsion = typeof(AppDomain).GetMethod("GetFusionContext", BindingFlags.NonPublic | BindingFlags.Instance);
    
        m.Invoke(null, new object[] { funsion.Invoke(AppDomain.CurrentDomain, null), "PRIVATE_BINPATH", "Castle;Core;Module;UI;Misc;" });
    
    } 
    
    
    
    嗯,迫不及待的编译,运行!哇!
    
        /// </summary>
        [STAThread]
        static void Main()
        {
    
            AppDomain.CurrentDomain.SetupInformation.ConfigurationFile = "DataMyApp.Config";
            Application.Run(new MyAppForm());
        }
    ……在此调试,惊奇的发现这个属性设置居然完全没有效果,语句执行完后,该属性值依然是默认值。于是查文档啊,百度啊,谷歌啊~ 最后终于知道设置config的正确方法。
    
    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path); 
    
    嗯,这个这个……不是微软在害人吗
    

      

    AppDomainSetup setup = new AppDomainSetup();
     setup.ConfigurationFile = Path.GetFullPath(appConfig);
     AppDomain domain = AppDomain.CreateDomain(
     Guid.NewGuid().ToString(),
     AppDomain.CurrentDomain.Evidence,
     setup);
     domain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
     var ty= typeof(Program);
     Program prog = domain.CreateInstanceAndUnwrap(ty.Assembly.FullName, ty.FullName) as Program;
     prog.Method(args);
    
    最好不要hack。 以上来自stackoverflow
    最好不要hack
    

      

    动态编译

    /// <summary>
            /// 动态编译并执行代码
            /// </summary>
            /// <param name="code">代码</param>
            /// <param name="newPath">输出dll的路径</param>
            /// <returns>返回输出内容</returns>
            private CompilerResults debugRun(string[] code, string newPath)
            {
                CSharpCodeProvider complier = new CSharpCodeProvider();
                //设置编译参数
                CompilerParameters paras = new CompilerParameters();
                //引入第三方dll
                paras.ReferencedAssemblies.Add(@"System.dll");
                paras.ReferencedAssemblies.Add(@"System.configuration.dll");
                paras.ReferencedAssemblies.Add(@"System.Data.dll");
                paras.ReferencedAssemblies.Add(@"System.Management.dll");
                paras.ReferencedAssemblies.Add(@"System.Web.dll");
                paras.ReferencedAssemblies.Add(@"System.Xml.dll");
                paras.ReferencedAssemblies.Add(@"F:AuthorizationServiceLibNewtonsoft.JsonNet20Newtonsoft.Json.dll");
                //引入自定义dll
                //paras.ReferencedAssemblies.Add(@"D:自定义方法自定义方法inLogHelper.dll");
                //是否内存中生成输出
                paras.GenerateInMemory = false;
                //是否生成可执行文件
                paras.GenerateExecutable = false;
                paras.OutputAssembly = newPath;
    
                //编译代码
                CompilerResults result = complier.CompileAssemblyFromSource(paras, code);
    
                return result;
            }
    

      

    using System;
    using System.Data;
    using System.Configuration;
    using System.Text;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Reflection;
    
    namespace EvalGuy
    {
        /// <summary>
        /// 本类用来将字符串转为可执行文本并执行
        /// 从别处复制,勿随意更改!
        /// </summary>
        public class Evaluator
        {
            #region 构造函数
            /// <summary>
            /// 可执行串的构造函数
            /// </summary>
            /// <param name="items">
            /// 可执行字符串数组
            /// </param>
            public Evaluator(EvaluatorItem[] items)
            {
                ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
            }
            /// <summary>
            /// 可执行串的构造函数
            /// </summary>
            /// <param name="returnType">返回值类型</param>
            /// <param name="expression">执行表达式</param>
            /// <param name="name">执行字符串名称</param>
            public Evaluator(Type returnType, string expression, string name)
            {
                //创建可执行字符串数组
                EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
                ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
            }
            /// <summary>
            /// 可执行串的构造函数
            /// </summary>
            /// <param name="item">可执行字符串项</param>
            public Evaluator(EvaluatorItem item)
            {
                EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组
                ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
            }
            /// <summary>
            /// 解析字符串构造函数
            /// </summary>
            /// <param name="items">待解析字符串数组</param>
            private void ConstructEvaluator(EvaluatorItem[] items)
            {
    
                
                //创建C#编译器实例
                ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
                //编译器的传入参数
                CompilerParameters cp = new CompilerParameters();
    
                cp.ReferencedAssemblies.Add("system.dll");                //添加程序集 system.dll 的引用
                cp.ReferencedAssemblies.Add("system.data.dll");            //添加程序集 system.data.dll 的引用
                cp.ReferencedAssemblies.Add("system.xml.dll");            //添加程序集 system.xml.dll 的引用
                cp.GenerateExecutable = false;    //不生成可执行文件
                
                cp.GenerateInMemory = true;                                //在内存中运行
    
                StringBuilder code = new StringBuilder();                //创建代码串
                /*
                 *  添加常见且必须的引用字符串
                 */
                code.Append("using System; 
    ");
                code.Append("using System.Data; 
    ");
                code.Append("using System.Data.SqlClient; 
    ");
                code.Append("using System.Data.OleDb; 
    ");
                code.Append("using System.Xml; 
    ");
    
                code.Append("namespace EvalGuy { 
    ");                    //生成代码的命名空间为EvalGuy,和本代码一样
    
                code.Append(" static class Program{ static void Main(){}}
    ");//无用的M
    
                code.Append("  public class _Evaluator { 
    ");            //产生 _Evaluator 类,所有可执行代码均在此类中运行
                foreach (EvaluatorItem item in items)                //遍历每一个可执行字符串项
                {
                    code.AppendFormat("    public {0} {1}() ",            //添加定义公共函数代码
                                      item.ReturnType.Name,                //函数返回值为可执行字符串项中定义的返回值类型
                                      item.Name);                        //函数名称为可执行字符串项中定义的执行字符串名称
                    code.Append("{ ");                                    //添加函数开始括号
                    code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值
                    code.Append("}
    ");                                    //添加函数结束括号
                }
                code.Append("} }");                                    //添加类结束和命名空间结束括号
    
                //得到编译器实例的返回结果
                CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());
    
                if (cr.Errors.HasErrors)                            //如果有错误
                {
                    StringBuilder error = new StringBuilder();            //创建错误信息字符串
                    error.Append("编译有错误的表达式: ");                //添加错误文本
                    foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误
                    {
                        error.AppendFormat("{0}
    ", err.ErrorText);        //添加进错误文本,每个错误后换行
                    }
                    throw new Exception("编译错误: " + error.ToString());//抛出异常
                }
                Assembly a = cr.CompiledAssembly;       //获取编译器实例的程序集
                
                _Compiled = a.CreateInstance("EvalGuy._Evaluator");        //通过程序集查找并声明 EvalGuy._Evaluator 的实例
            }
            #endregion
    
            #region 公有成员
            /// <summary>
            /// 执行字符串并返回整型值
            /// </summary>
            /// <param name="name">执行字符串名称</param>
            /// <returns>执行结果</returns>
            public int EvaluateInt(string name)
            {
                return (int)Evaluate(name);
            }
            /// <summary>
            /// 执行字符串并返回字符串型值
            /// </summary>
            /// <param name="name">执行字符串名称</param>
            /// <returns>执行结果</returns>
            public string EvaluateString(string name)
            {
                return (string)Evaluate(name);
            }
            /// <summary>
            /// 执行字符串并返回布尔型值
            /// </summary>
            /// <param name="name">执行字符串名称</param>
            /// <returns>执行结果</returns>
            public bool EvaluateBool(string name)
            {
                return (bool)Evaluate(name);
            }
            /// <summary>
            /// 执行字符串并返 object 型值
            /// </summary>
            /// <param name="name">执行字符串名称</param>
            /// <returns>执行结果</returns>
            public object Evaluate(string name)
            {
                MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用
                return mi.Invoke(_Compiled, null);                    //执行 mi 所引用的方法
            }
            #endregion
    
            #region 静态成员
            /// <summary>
            /// 执行表达式并返回整型值
            /// </summary>
            /// <param name="code">要执行的表达式</param>
            /// <returns>运算结果</returns>
            static public int EvaluateToInteger(string code)
            {
                Evaluator eval = new Evaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像
                return (int)eval.Evaluate(staticMethodName);                        //执行并返回整型数据
            }
            /// <summary>
            /// 执行表达式并返回字符串型值
            /// </summary>
            /// <param name="code">要执行的表达式</param>
            /// <returns>运算结果</returns>
            static public string EvaluateToString(string code)
            {
                Evaluator eval = new Evaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像
                return (string)eval.Evaluate(staticMethodName);                        //执行并返回字符串型数据
            }
            /// <summary>
            /// 执行表达式并返回布尔型值
            /// </summary>
            /// <param name="code">要执行的表达式</param>
            /// <returns>运算结果</returns>
            static public bool EvaluateToBool(string code)
            {
                Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像
                return (bool)eval.Evaluate(staticMethodName);                        //执行并返回布尔型数据
            }
            /// <summary>
            /// 执行表达式并返回 object 型值
            /// </summary>
            /// <param name="code">要执行的表达式</param>
            /// <returns>运算结果</returns>
            static public object EvaluateToObject(string code)
            {
                Evaluator eval = new Evaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像
                return eval.Evaluate(staticMethodName);                                //执行并返回 object 型数据
            }
            #endregion
    
            #region 私有成员
            /// <summary>
            /// 静态方法的执行字符串名称
            /// </summary>
            private const string staticMethodName = "__foo";
            /// <summary>
            /// 用于动态引用生成的类,执行其内部包含的可执行字符串
            /// </summary>
            object _Compiled = null;
            #endregion
        }
        /// <summary>
        /// 可执行字符串项(即一条可执行字符串)
        /// </summary>
        public class EvaluatorItem
        {
            /// <summary>
            /// 返回值类型
            /// </summary>
            public Type ReturnType;
            /// <summary>
            /// 执行表达式
            /// </summary>
            public string Expression;
            /// <summary>
            /// 执行字符串名称
            /// </summary>
            public string Name;
            /// <summary>
            /// 可执行字符串项构造函数
            /// </summary>
            /// <param name="returnType">返回值类型</param>
            /// <param name="expression">执行表达式</param>
            /// <param name="name">执行字符串名称</param>
            public EvaluatorItem(Type returnType, string expression, string name)
            {
                ReturnType = returnType;
                Expression = expression;
                Name = name;
            }
        }
    }
    

       EvalGuy.Evaluator ev = new EvalGuy.Evaluator(typeof(string), ""dddd"+DateTime.Now+""", "ddd");
               Text= ev.EvaluateString("ddd");

    http://www.csscript.net/

    private void menu_export_Click(object sender, EventArgs e)
            {
                string sourceName = "MyForm.cs";
                FileInfo sourceFile = new FileInfo(sourceName);
                CSharpCodeProvider provider = new CSharpCodeProvider();
    
                status_content_label.Text = "Exporting ... ";
    
                String exeName = String.Format(@"{0}{1}.exe", "Output/", sourceFile.Name.Replace(".", "_"));
    
                CompilerParameters cp = new CompilerParameters();
    
                cp.ReferencedAssemblies.Add("System.dll");
                cp.ReferencedAssemblies.Add("System.Drawing.dll");
                cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
                //cp.ReferencedAssemblies.Add("AxInterop.ShockwaveFlashObjects.dll");
                //cp.ReferencedAssemblies.Add("Interop.ShockwaveFlashObjects.dll");
                //cp.ReferencedAssemblies.Add("System.Data.dll");
    
                // Generate an executable instead of 
                // a class library.
                cp.GenerateExecutable = true;
    
                // Specify the assembly file name to generate.
                cp.OutputAssembly = exeName;
    
                // Save the assembly as a physical file.
                cp.GenerateInMemory = false;
    
                cp.IncludeDebugInformation = false;
    
                // Set whether to treat all warnings as errors.
                cp.TreatWarningsAsErrors = false;
    
                cp.CompilerOptions = "/optimize /win32icon:" + config.GetIconPath() + " MyForm.cs";
    
                // Invoke compilation of the source file.
                CompilerResults cr = provider.CompileAssemblyFromFile(cp, sourceName);
    
                string errorMessage;
    
                if (cr.Errors.Count > 0)
                {
                    // Display compilation errors.
                    errorMessage = "Errors building {0} into {1}" + sourceName + cr.PathToAssembly + "
    ";
                    foreach (CompilerError ce in cr.Errors)
                    {
                        errorMessage += "  {0}" + ce.ToString() + "
    ";
                    }
                    errorReport.ShowError(errorMessage);
                    errorReport.Show();
    
                    status_content_label.Text = "Failed to create the exe file.";
                }
                else
                {
                    status_content_label.Text = "Exe file successfully created.";
                }
            }
    

      然后是MyForm.cs,就是用来动态编译的cs:

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    
    class MyForm : Form
    {
        public MyForm()
        {
            this.Text = "Hello World";
            this.StartPosition = FormStartPosition.CenterScreen;
        }
    
        public static void Main()
        {
            Application.Run(new MyForm());
        }
    }
    

      在 cp.CompilerOptions 中 加一句 /target:winexe 就可以了 默认是 Console app
    http://stackoverflow.com/questions/7497493/problems-using-windowsform-and-csharpcodeprovider

    public static void abc()
             {
                 #region 要执行的代码
    
                string strCode = @" 
     using System;
     using System.Text;
     using System.Collections.Generic;
     using System.Linq;
     namespace aaa
     {
         public class bbb
         {
             public static string ccc(string name)
             {
                 return ""abc"";
             }
         }
     }";
                 #endregion
                 #region 编译参数
                CompilerParameters objCompilerParams = new CompilerParameters();
    
                 objCompilerParams.GenerateExecutable = false;   //编译成exe还是dll
                 objCompilerParams.GenerateInMemory = false;           //是否写入内存,不写入内存就写入磁盘
                objCompilerParams.OutputAssembly = "E:\abc.dll";         //输出路径
                objCompilerParams.IncludeDebugInformation = false; //是否产生pdb调试文件      默认是false
                 objCompilerParams.ReferencedAssemblies.Add("System.dll");
                 objCompilerParams.ReferencedAssemblies.Add("System.Core.dll");
    
                 //编译器选项:编译成(存储在内存中)的DLL
                 /*objCompilerParams.CompilerOptions = "/target:library /optimize";
                 //编译时在内存输出 
                 objCompilerParams.GenerateInMemory = true;
                 //不生成调试信息 
                 objCompilerParams.IncludeDebugInformation = false;*/
                 #endregion
                 #region 编译
                //创建编译类
                CSharpCodeProvider objCompiler = new CSharpCodeProvider();
                 //进行编译
                CompilerResults objCompileResults = objCompiler.CompileAssemblyFromSource(objCompilerParams, strCode);
                 #endregion
                 #region 取得编译成程序集,准备执行程序集里的类中的方法
                //获取编译结果:程序集
                Assembly objAssembly = objCompileResults.CompiledAssembly;
                 //获取编译成的程序集的信息
                /*object objMainClassInstance = objAssembly.CreateInstance("Program");
                 Type objMainClassType = objMainClassInstance.GetType();*/
                 #endregion
                 #region 调用程序集中的类,执行类中的方法,得到结果
                /*objMainClassType.GetMethod("Main").Invoke(objMainClassInstance, null);
                 objMainClassType.GetMethod("PrintWorld").Invoke(objMainClassInstance, null);*/
                 #endregion
    
    上面代码是动态编译生成一个DLL,生成没问题,现在DLL中的方法返回的是字符串!!如何在动态库中使用图片资源?例如上面的方法,我可以返回一个image  求大神帮忙 
    

      

    objCompilerParams.EmbeddedResources.Add(fileName);
    
    //获取资源中的图片
     
            protected Bitmap GetResImage(string resourceName)
            {
                Bitmap resImage = null;
                try
                {
                    Stream stream = this.GetType().Assembly.GetManifestResourceStream(resourceName);
     
                    if (stream != null)
                    {
                        Bitmap bmp = new Bitmap(stream);
                        resImage = CloneBitmap(bmp);
                        bmp = null;
                        stream.Close();
                        stream = null;
                    }
                }
                catch { }
                return resImage;
     
            }
    
    
    
    
    终于OK了!!
    
    Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(projectName + "".bbb.jpg"");
    
    后面的文件名这样写不对!!!
    
      var ass = Assembly.GetExecutingAssembly();
                 foreach (var file in ass.GetManifestResourceNames())
                 {
    
                 }
    
    直接用这个file就可以了!~!!感谢各位这两天的帮忙!!!散分了 
    

      

  • 相关阅读:
    js组件常用封装方法。。。。。【组件封装】 ★★★★★★ 1月会员日 集人气【弹窗】
    以后开公司用的资源瞎记录
    SpringSecurityFilter 链
    分布式系统数据一致性的6种方案(转)
    统一日志监控系统 springboot websocket 作品
    MyBatis generator 使用方式 小结
    swagger and restful api 参考
    kafka linux 启动脚本 sample
    转 CAS实现SSO单点登录原理
    江南白衣 Java性能优化PPT
  • 原文地址:https://www.cnblogs.com/xiangxiong/p/7373476.html
Copyright © 2011-2022 走看看