CSDN博客

img chjl

动态生成和编译源代码

发表于2004/6/29 7:15:00  867人阅读


// 以前遇到不熟悉的属性或函数时,我会新建一个控制台程序,然后写要测试的属性或函数,然后编译在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();
  }
 }
}

0 0

相关博文

我的热门文章

img
取 消
img