(轉+整理)C#中動態執行代碼

來源:互聯網
上載者:User

標籤:message   代碼執行   自己   enc   rpc   ESS   generic   objc   .dll   

通過微軟提供的CSharpCodeProvider,CompilerParameters,CompilerResults等類,可以在運行時,動態執行自己寫的代碼檔案。原理就是把你的代碼檔案動態編譯成exe或dll,或者在記憶體中輸出,然後通過Assembly進行反射,執行其中的方法或訪問其中的屬性等。

介面有兩個按鈕,一個執行ShowMessage方法,另一個執行ShowForm方法,代碼如下:

需引入

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;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;

namespace CodeTest
{
  public partial class Test : Form
  {
    public Test()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
      CompilerParameters objCompilerParameters = new CompilerParameters();

      objCompilerParameters.ReferencedAssemblies.Add("System.dll");
      objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

      objCompilerParameters.GenerateExecutable = false;
      objCompilerParameters.GenerateInMemory = true;

      CompilerResults cresult = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, textBox1.Text);

      if (cresult.Errors.HasErrors)
      {
        foreach (CompilerError err in cresult.Errors)
        {
          MessageBox.Show(err.ErrorText);
        }
      }
      else
      {
        // 通過反射,執行代碼
        Assembly objAssembly = cresult.CompiledAssembly;
        object obj = objAssembly.CreateInstance("CodeTest.Test");
        MethodInfo objMI = obj.GetType().GetMethod("ShowMessage");
        objMI.Invoke(obj, new object[] { "This is CodeTest!" });
      }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      textBox1.Text = "using System;" + Environment.NewLine +
             "using System.Windows.Forms;" + Environment.NewLine +
             Environment.NewLine +
             "namespace CodeTest" + Environment.NewLine +
             "{" + Environment.NewLine +
             " public partial class Test" + Environment.NewLine +
             " {" + Environment.NewLine +
             ‘\t‘ + "public void ShowMessage(string msg)" + Environment.NewLine +
             ‘\t‘ + "{" + Environment.NewLine +
             ‘\t‘ + " MessageBox.Show(msg);" + Environment.NewLine +
             ‘\t‘ + "}" + Environment.NewLine +
             Environment.NewLine +
             ‘\t‘ + "public void ShowForm()" + Environment.NewLine +
             ‘\t‘ + "{" + Environment.NewLine +
             ‘\t‘ + " Form frm = new Form();" + Environment.NewLine +
             ‘\t‘ + " frm.Show();" + Environment.NewLine +
             ‘\t‘ + "}" + Environment.NewLine +
             " }" + Environment.NewLine +
             "}";
    }

    private void button2_Click(object sender, EventArgs e)
    {

      CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
      CompilerParameters objCompilerParameters = new CompilerParameters();

      objCompilerParameters.ReferencedAssemblies.Add("System.dll");
      objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

      objCompilerParameters.GenerateExecutable = false;
      objCompilerParameters.GenerateInMemory = true;

      CompilerResults cresult = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, textBox1.Text);

      if (cresult.Errors.HasErrors)
      {
        foreach (CompilerError err in cresult.Errors)
        {
          MessageBox.Show(err.ErrorText);
        }
      }
      else
      {
        // 通過反射,執行代碼
        Assembly objAssembly = cresult.CompiledAssembly;
        object obj = objAssembly.CreateInstance("CodeTest.Test");
        MethodInfo objMI = obj.GetType().GetMethod("ShowForm");
        objMI.Invoke(obj, null);
      }
    }
  }
}

點擊按鈕“執行代碼”,運行結果如下:

點擊按鈕“顯示表單”,代碼執行如下:

 

因為自訂代碼中有

using System;
using System.Windows.Forms;

需要上面兩個類庫才能執行,所以要在CompilerParameters中對這兩個dll添加引用,既

objCompilerParameters.ReferencedAssemblies.Add("System.dll");

objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");

反射時,命名空間的名字要寫完整,執行個體中命名空間是CodeTest,類是Test,所以反射代碼是objAssembly.CreateInstance("CodeTest.Test")

文章轉載自22398077

(轉+整理)C#中動態執行代碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.