温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

动态编译程序与创建卸载程序域

发布时间:2020-07-10 23:06:04 来源:网络 阅读:1492 作者:1473348968 栏目:编程语言

 

==============================================动态编译程序思路

     * 0,把C#以字符串的方式放在string对象里
     * 1,实例化一个C#编译器:CSharpCodeProvider
     * 2,创建编译器环境(并配置环境):CompilerParameters
     * 3,开始编译:ccp.CompileAssemblyFromSource(cp, abc);
     * 4,返回编译结果:CompilerResults
     * 【5,可以使用反射调用该程序集】

==============================================什么是程序域?

在.net技术之前,进程做为应用程序独立的边界,

.net体系结构中,应用程序有一个新的边界,就是程序域。可以合理分配对象在不同的程序域中,

可以对程序域进行卸载

动态编译程序与创建卸载程序域

 ==============================================程序域的作用

如果程序集是动态加载的,且需要在使用完后卸载程序集,应用程序域就非常有
用。 在主应用程序域中,不能删除已加载的程序集,但可以终止应用程序域,在该应
用程序域中载的所有程序集都会从内存中清除。

 

==============================================例子:

动态编译程序与创建卸载程序域

动态编译程序与创建卸载程序域

 

--------------------------------------CompileType.cs(枚举文件)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppDomainDemo {     public enum CompileType     {         Console,//控制台输出         File//输出文件     } }

 

--------------------------------------CompileCode.cs(动态编译程序代码类)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Reflection; using Microsoft.CSharp;//提供对 C# 代码生成器和代码编译器的实例的访问。 using System.CodeDom.Compiler;//用途是对所支持编程语言的源代码的生成和编译进行管理 namespace AppDomainDemo {     //MarshalByRefObject:跨域访问必须要继承此类     public class CompileCode : MarshalByRefObject     {         public string CompileCodeGo(string input, CompileType ct, out bool IsError)         {             StringBuilder sb1 = new StringBuilder();             sb1.Append("using System;");             sb1.Append("using System.Windows.Forms;");             sb1.Append("public class Program{public static void Main(string[] args){");             StringBuilder sb2 = new StringBuilder();             sb2.Append("}");             sb2.Append("public void aa(){");             string bottom = "}}";             //编译器             CSharpCodeProvider ccp = new CSharpCodeProvider();             //编译参数配置             CompilerParameters cp = new CompilerParameters();             //编译结果             CompilerResults cr;             //控制台输出             if (ct == CompileType.Console)             {                 //设置是否在内存中生成输出                 cp.GenerateInMemory = true;             }             else//编译为可执行文件             {                 //是否是可执行文件                 cp.GenerateExecutable = true;                 //配置输出文件路径                 cp.OutputAssembly = Directory.GetCurrentDirectory() + "/" + DateTime.Now.ToString("yyyyMMhhddmmss") + ".exe";             }             //引用程序集             cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");                          //编译             cr = ccp.CompileAssemblyFromSource(cp, sb1.ToString() + input + sb2.ToString() + input + bottom);             if (cr.Errors.HasErrors)//编辑结果出现异常             {                 IsError = true;                 string error = "";                 for (int i = 0; i < cr.Errors.Count; i++)                 {                     error += string.Format("影响行数:{0},错误信息:{1}\r\n", cr.Errors[i].Line.ToString(), cr.Errors[i].ErrorText);                 }                 return error;             }             else             {                 IsError = false;                 //用于接受控制台输出的信息                 StringWriter sw = new StringWriter();                 Console.SetOut(sw);                 //获取编译的程序集[反射]                 Assembly asb = cr.CompiledAssembly;                 //获取类                 Type t = asb.GetType("Program");                 //非静态方法需要实例化类                 object o = Activator.CreateInstance(t);                 //获取方法                 MethodInfo m = t.GetMethod("aa");                 //执行方法                 m.Invoke(o, null);                 //返回控制台输出的结果                 return sw.ToString();             }         }     } }

 

--------------------------------------AppDomainCode.cs(创建卸载程序域类)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AppDomainDemo {     public class AppDomainCode     {         public string AppDomainCodeGo(string input, CompileType ct, out bool IsError)         {             //创建程序域             AppDomain app = AppDomain.CreateDomain("zhangdi");             //创建制定类型的实例             CompileCode cc = (CompileCode)app.CreateInstanceAndUnwrap("AppDomainDemo", "AppDomainDemo.CompileCode");                          string result= cc.CompileCodeGo(input, ct, out IsError);             //卸载程序域             AppDomain.Unload(app);             return result;         }     } }

 

--------------------------------------Form1.cs(窗体后台程序)

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AppDomainDemo {     /*      *************************************      *代码不能为Console.ReadKey();      *点击 点击我输出控制台 按钮【出现错误:调用的目标发生了异常】      *这个错误我找了好几天,坑爹      *************************************      */     public partial class Form1 : Form     {         public Form1()         {             InitializeComponent();         }         string str = "Console.WriteLine(\"aasdasd\");Console.ReadLine();";         /// <summary>         /// 点我输出控制台         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         private void btnConsole_Click(object sender, EventArgs e)         {             AppDomainCode adc = new AppDomainCode();             bool iserror;             string result = adc.AppDomainCodeGo(str, CompileType.Console, out iserror);             richTextBox1.Text = result;         }         /// <summary>         /// 点我输出可执行文件         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         private void btnFile_Click(object sender, EventArgs e)         {             AppDomainCode adc = new AppDomainCode();             bool iserror;             string result = adc.AppDomainCodeGo(str, CompileType.File, out iserror);             richTextBox1.Text = result;         }     } }

 

 

 

 

 

 

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI