溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

動(dòng)態(tài)編譯程序與創(chuàng)建卸載程序域

發(fā)布時(shí)間:2020-07-10 23:06:04 來(lái)源:網(wǎng)絡(luò) 閱讀:1452 作者:1473348968 欄目:編程語(yǔ)言

 

==============================================動(dòng)態(tài)編譯程序思路

     * 0,把C#以字符串的方式放在string對(duì)象里
     * 1,實(shí)例化一個(gè)C#編譯器:CSharpCodeProvider
     * 2,創(chuàng)建編譯器環(huán)境(并配置環(huán)境):CompilerParameters
     * 3,開(kāi)始編譯:ccp.CompileAssemblyFromSource(cp, abc);
     * 4,返回編譯結(jié)果:CompilerResults
     * 【5,可以使用反射調(diào)用該程序集】

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

在.net技術(shù)之前,進(jìn)程做為應(yīng)用程序獨(dú)立的邊界,

.net體系結(jié)構(gòu)中,應(yīng)用程序有一個(gè)新的邊界,就是程序域??梢院侠矸峙鋵?duì)象在不同的程序域中,

可以對(duì)程序域進(jìn)行卸載

動(dòng)態(tài)編譯程序與創(chuàng)建卸載程序域

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

如果程序集是動(dòng)態(tài)加載的,且需要在使用完后卸載程序集,應(yīng)用程序域就非常有
用。 在主應(yīng)用程序域中,不能刪除已加載的程序集,但可以終止應(yīng)用程序域,在該應(yīng)
用程序域中載的所有程序集都會(huì)從內(nèi)存中清除。

 

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

動(dòng)態(tài)編譯程序與創(chuàng)建卸載程序域

動(dòng)態(tài)編譯程序與創(chuàng)建卸載程序域

 

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppDomainDemo
{
    public enum CompileType
    {
        Console,//控制臺(tái)輸出
        File//輸出文件
    }
}

 

--------------------------------------CompileCode.cs(動(dòng)態(tài)編譯程序代碼類(lèi))

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;//提供對(duì) C# 代碼生成器和代碼編譯器的實(shí)例的訪問(wèn)。
using System.CodeDom.Compiler;//用途是對(duì)所支持編程語(yǔ)言的源代碼的生成和編譯進(jìn)行管理
namespace AppDomainDemo
{
    //MarshalByRefObject:跨域訪問(wèn)必須要繼承此類(lèi)
    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();
            //編譯參數(shù)配置
            CompilerParameters cp = new CompilerParameters();
            //編譯結(jié)果
            CompilerResults cr;
            //控制臺(tái)輸出
            if (ct == CompileType.Console)
            {
                //設(shè)置是否在內(nèi)存中生成輸出
                cp.GenerateInMemory = true;
            }
            else//編譯為可執(zhí)行文件
            {
                //是否是可執(zhí)行文件
                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)//編輯結(jié)果出現(xiàn)異常
            {
                IsError = true;
                string error = "";
                for (int i = 0; i < cr.Errors.Count; i++)
                {
                    error += string.Format("影響行數(shù):{0},錯(cuò)誤信息:{1}\r\n", cr.Errors[i].Line.ToString(), cr.Errors[i].ErrorText);
                }
                return error;
            }
            else
            {
                IsError = false;
                //用于接受控制臺(tái)輸出的信息
                StringWriter sw = new StringWriter();
                Console.SetOut(sw);
                //獲取編譯的程序集[反射]
                Assembly asb = cr.CompiledAssembly;
                //獲取類(lèi)
                Type t = asb.GetType("Program");
                //非靜態(tài)方法需要實(shí)例化類(lèi)
                object o = Activator.CreateInstance(t);
                //獲取方法
                MethodInfo m = t.GetMethod("aa");
                //執(zhí)行方法
                m.Invoke(o, null);
                //返回控制臺(tái)輸出的結(jié)果
                return sw.ToString();
            }

        }
    }
}

 

--------------------------------------AppDomainCode.cs(創(chuàng)建卸載程序域類(lèi))

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)
        {
            //創(chuàng)建程序域
            AppDomain app = AppDomain.CreateDomain("zhangdi");
            //創(chuàng)建制定類(lèi)型的實(shí)例
            CompileCode cc = (CompileCode)app.CreateInstanceAndUnwrap("AppDomainDemo", "AppDomainDemo.CompileCode");
            
            string result= cc.CompileCodeGo(input, ct, out IsError);
            //卸載程序域
            AppDomain.Unload(app);
            return result;
        }
    }
}

 

--------------------------------------Form1.cs(窗體后臺(tái)程序)

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();
     *點(diǎn)擊 點(diǎn)擊我輸出控制臺(tái) 按鈕【出現(xiàn)錯(cuò)誤:調(diào)用的目標(biāo)發(fā)生了異常】
     *這個(gè)錯(cuò)誤我找了好幾天,坑爹
     *************************************
     */
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string str = "Console.WriteLine(\"aasdasd\");Console.ReadLine();";
        /// <summary>
        /// 點(diǎn)我輸出控制臺(tái)
        /// </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>
        /// 點(diǎn)我輸出可執(zhí)行文件
        /// </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問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI