动态生成和编译源代码

原创 2004年06月29日 07:15:00


// 以前遇到不熟悉的属性或函数时,我会新建一个控制台程序,然后写要测试的属性或函数,然后编译在Concle中查看,感觉挺麻烦,于是写了下面这段代码,可以输入你的一些想测试的代码,然后显示出来,感觉方便多了。

// 动态生成和编译源代码
using Microsoft.CSharp;
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.IO;

namespace cjl
{
 public delegate string Run();
 
 public class Form1 : System.Windows.Forms.Form
 {
  Run run;
  private System.Windows.Forms.Label label2;
  private System.Windows.Forms.Button RunCode;
  private System.Windows.Forms.TextBox Code;
  private System.Windows.Forms.Label Result;
  private System.Windows.Forms.TextBox CodeOutput;
  private System.ComponentModel.Container components = null;

  public Form1()
  {
   InitializeComponent();
  }

  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows Form Designer generated code

  private void InitializeComponent()
  {
   this.RunCode = new System.Windows.Forms.Button();
   this.Code = new System.Windows.Forms.TextBox();
   this.Result = new System.Windows.Forms.Label();
   this.label2 = new System.Windows.Forms.Label();
   this.CodeOutput = new System.Windows.Forms.TextBox();
   this.SuspendLayout();
   //
   // RunCode
   //
   this.RunCode.Location = new System.Drawing.Point(40, 104);
   this.RunCode.Name = "RunCode";
   this.RunCode.Size = new System.Drawing.Size(336, 23);
   this.RunCode.TabIndex = 1;
   this.RunCode.Text = "运行代码";
   this.RunCode.Click += new System.EventHandler(this.button1_Click);
   //
   // Code
   //
   this.Code.Location = new System.Drawing.Point(40, 16);
   this.Code.Multiline = true;
   this.Code.Name = "Code";
   this.Code.Size = new System.Drawing.Size(336, 80);
   this.Code.TabIndex = 2;
   this.Code.Text = "// 最后一句必须return字符串类型 /r/nint i = 2;/r/nstring s = /"ssss/";/r/nreturn string.Concat(i, s);";
   //
   // Result
   //
   this.Result.Location = new System.Drawing.Point(40, 136);
   this.Result.Name = "Result";
   this.Result.Size = new System.Drawing.Size(336, 160);
   this.Result.TabIndex = 3;
   this.Result.Text = "显示结果";
   //
   // label2
   //
   this.label2.Location = new System.Drawing.Point(0, 24);
   this.label2.Name = "label2";
   this.label2.Size = new System.Drawing.Size(32, 23);
   this.label2.TabIndex = 4;
   this.label2.Text = "代码";
   //
   // CodeOutput
   //
   this.CodeOutput.Location = new System.Drawing.Point(384, 16);
   this.CodeOutput.Multiline = true;
   this.CodeOutput.Name = "CodeOutput";
   this.CodeOutput.Size = new System.Drawing.Size(320, 288);
   this.CodeOutput.TabIndex = 5;
   this.CodeOutput.Text = "";
   //
   // Form1
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(712, 317);
   this.Controls.AddRange(new System.Windows.Forms.Control[] {
                    this.CodeOutput,
                    this.label2,
                    this.Result,
                    this.Code,
                    this.RunCode});
   this.Name = "Form1";
   this.Text = "Form1";
   this.ResumeLayout(false);

  }
  #endregion

  [STAThread]
  static void Main()
  {
   Application.Run(new Form1());
  }

  private void button1_Click(object sender, System.EventArgs e)
  {
   
   if (this.Code.Text.LastIndexOf("return ") < 0)
   {
    string message = "必须包含reuturn,并且返回的类型是string类型。";
    MessageBox.Show(message);
    Result.Text = message;
    return;
   }

   CSharpCodeProvider codeProvider = new CSharpCodeProvider();
   ICodeGenerator codeGenerator = codeProvider.CreateGenerator();

   CodeNamespace ns = new CodeNamespace("cjl");
   ns.Comments.Add(new CodeCommentStatement("名称空间注释"));

   // 如果在运行时出现错误,有可能你所输入的代码在其它名称空间中,请在此加入更多CodeNamespaceImport
   ns.Imports.Add(new CodeNamespaceImport("System"));
   ns.Imports.Add(new CodeNamespaceImport("System.IO"));

   CodeTypeDeclaration testClass = new CodeTypeDeclaration("Test");
   testClass.TypeAttributes = TypeAttributes.Public;
   testClass.IsClass = true;
   ns.Types.Add(testClass);

   CodeMemberMethod function = new CodeMemberMethod();
   function.Attributes = MemberAttributes.Public;
   function.Name = "Try";
   function.ReturnType = new CodeTypeReference(typeof(string));

   foreach (string s in this.Code.Text.Split(';'))
   {
    function.Statements.Add(new CodeSnippetStatement(s + ";"));
   }

   
   testClass.Members.Add(function);
   
   // 写入文件
   TextWriter writer = new StreamWriter(new FileStream("Temp.cs", FileMode.Create));
   CodeGeneratorOptions options = new CodeGeneratorOptions();
   options.BracingStyle = "C";
   codeGenerator.GenerateCodeFromNamespace(ns, writer, options);
   writer.Close();

 
   CodeOutput.Text = new StreamReader(new FileStream("Temp.cs", FileMode.Open)).ReadToEnd();


   CodeCompileUnit compileUnit = new CodeCompileUnit();
   compileUnit.Namespaces.Add(ns);
   
   CompilerParameters compilerParameters = new CompilerParameters();
   compilerParameters.GenerateInMemory=true;
   
   ICodeCompiler csharpCompiler = codeProvider.CreateCompiler();
   CompilerResults compilerResults = csharpCompiler.CompileAssemblyFromDom(compilerParameters,compileUnit);
   if ( compilerResults != null && compilerResults.Errors.Count > 0 )
   {
    foreach( CompilerError err in compilerResults.Errors )
    {
     Result.Text = err.ToString() + "/n";
    }
   }
         
   object o = compilerResults.CompiledAssembly.CreateInstance("cjl.Test",true);
   run = (Run) Delegate.CreateDelegate(typeof(Run), o, function.Name);
 
   this.Result.Text = "运行以上代码结果如下:/n/n" + run();
  }
 }
}

Dubbo源码分析(六):Dubbo内核实现之动态编译

我们运行的java代码,一般都是编译之后的字节码。Dubbo为了实现基于spi思想的扩展特性,特别是能够灵活添加额外功能,对于扩展或者说是策略的选择这个叫做控制类也好设配类也好的类要能够动态生成。当然...
  • ZuoAnYinXiang
  • ZuoAnYinXiang
  • 2016年05月07日 15:10
  • 1947

Java动态编译源代码并加载执行

最近在看研究Hadoop时,发现官方文档中使用com.sun.tools.javac.Main编译Java源代码的,脚本如下。就研究了一番,写了个demo,记录一下,也方便后来人学习。 $ bin/...
  • Deveper
  • Deveper
  • 2017年01月08日 19:25
  • 1313

jsp页面动态生成页面源代码

支付渠道选择页面 /css/func.css
  • z_play_du
  • z_play_du
  • 2012年12月08日 14:28
  • 501

vc动态生成控件源代码

1. CListCtrl 控件;     [c-sharp:showcolumns] view plaincopy ·········10·...
  • lingxiu0613
  • lingxiu0613
  • 2012年09月04日 16:20
  • 402

Java 编程的动态性,第 8 部分: 用代码生成取代反射

既然您已经看到了如何使用 Javassist 和 BCEL 框架来进行 classworking (请参阅 本系列以前的一组文章), 我将展示一个实际的 classworking 应用程序。这个应...
  • yczz
  • yczz
  • 2013年11月07日 22:52
  • 1742

多源代码文件程序的编译

使用多个函数的最简单方法就是将它们放在同一文件中,然后像编译单个函数的文件一样对该文件进行编译。 1.UNIX 首先假定UNIX系统下安装了标准的编译器cc。文件file1.c和文件file2.c...
  • luoyeyeye
  • luoyeyeye
  • 2017年01月17日 19:46
  • 589

源代码和kernel编译

最新的android4.0源代码公布以后,相信很多人和我一样都跃跃欲试,其实4.0的代码下载和编译和以前的版本差不多,但是有一些小的差别,写下来供不明真相的新手来参考 首先,开发环境,google建...
  • lostinai
  • lostinai
  • 2014年01月02日 21:11
  • 574

编译——源程序是如何变成可执行文件的?

一:几个关键名词 1、编辑器:就是我们通常写代码的编辑工具,像notepad++ 等编辑工具,我们通过这类工具编辑我们想写的代码,所形成的文件称之为源文件; 2、预处理器:主要负责文本的替换、宏展开、...
  • xholes
  • xholes
  • 2017年03月20日 15:18
  • 990

(一〇九)单独编译(多个源代码文件和头文件)

单独编译的简单原理: C++在内存中储存数据提供了多种选择。   可以选择数据保留在内存中的时间长度(存储持续性)以及程序的哪一部分可以访问数据(作用域和链接)等。可以使用new来动态地分配内存...
  • qq20004604
  • qq20004604
  • 2016年01月11日 01:41
  • 1038

源代码的编译与安装

绝大多数来自“源头”的源代码都是封装成所谓的tarball格式。 何为tarball? 一般而言,有份量的Open Source软件都含有相当多的文件,包括源代码、说明文件、编译支持文件、配置文件...
  • hustspy1990
  • hustspy1990
  • 2010年03月31日 18:52
  • 5295
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:动态生成和编译源代码
举报原因:
原因补充:

(最多只允许输入30个字)