分享
 
 
 

使用CODEDOM动态实现代码的生成,编译

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

前一阶段一直在做一个基于VS.NET2k3的一个插件,大致功能是实现业务代码的自动生成。程序在前几天终于突破性的进展,所有的功能都能实现了。包括自动添加工程,引用,编译等。等再过些天,把代码进行优化一些(同时去除一些BUG,一直不明白,当产生几万行代码后,我的开发环境会全面崩溃了)再发布出来吧。昨天突然想到,现在产生的代码过于生,不能根据用户的选择来生成对应的语言的代码。如果死写的话,也太没意思了。想到以前曾看过MSDN里介绍过CODEDOM这玩意能生成各门语言的代码,能动态调用编译,于是快速将CODEDOM再看一次,果然能生成C#,VB,JSCRIPT的代码。不过刚开始研究,只写了一个小小的程序。不过也觉得很有意思的。这样的话,我只要将我的TOOLKIT重写一下就可以让不同的程序员根据自己的喜好生成对应的代码了(功能都是一样的。)

using System;

using System.CodeDom;

using System.CodeDom.Compiler;

using System.Collections;

using System.ComponentModel;

using System.Diagnostics;

using System.Drawing;

using System.IO;

using System.Windows.Forms;

using Microsoft.CSharp;

using Microsoft.VisualBasic;

using Microsoft.JScript;

//这个示例演示如何使用System.CodeDom来建立一个HELLO World程序,将会根据用户的选择动态代码生成及编译的C#,VB,JScript版本的程序集

namespace CodeDOMTest

{

public class CodeDomExampleForm : System.Windows.Forms.Form

{

private System.Windows.Forms.Button run_button = new System.Windows.Forms.Button();

private System.Windows.Forms.Button compile_button = new System.Windows.Forms.Button();

private System.Windows.Forms.Button generate_button = new System.Windows.Forms.Button();

private System.Windows.Forms.TextBox textBox1 = new System.Windows.Forms.TextBox();

private System.Windows.Forms.ComboBox comboBox1 = new System.Windows.Forms.ComboBox();

private System.Windows.Forms.Label label1 = new System.Windows.Forms.Label();

private void generate_button_Click(object sender, System.EventArgs e)

{

CodeDomProvider provider = GetCurrentProvider();

CodeDomExample.GenerateCode(provider, CodeDomExample.BuildHelloWorldGraph());

StreamReader sr = new StreamReader("MyHello.cs");

textBox1.Text = sr.ReadToEnd();

sr.Close();

}

private void compile_button_Click(object sender, System.EventArgs e)

{

CodeDomProvider provider = GetCurrentProvider();

CompilerResults cr = CodeDomExample.CompileCode(provider, "MyHello.cs");

if(cr.Errors.Count > 0)

{

textBox1.Text = "编译文件出错: "+cr.PathToAssembly+": \r\n";

foreach(CompilerError ce in cr.Errors)

textBox1.AppendText(ce.ToString()+"\r\n");

run_button.Enabled = false;

}

else

{

textBox1.Text = cr.PathToAssembly+" 编译成功";

run_button.Enabled = true;

}

}

private void run_button_Click(object sender, System.EventArgs e)

{

Process.Start("MyHello.exe");

}

/// <summary>

/// 根据用户的选择返回不同语言的代码生成器

/// </summary>

/// <returns></returns>

private CodeDomProvider GetCurrentProvider()

{

CodeDomProvider provider;

switch((string)this.comboBox1.SelectedItem)

{

case "CSharp":

provider = new CSharpCodeProvider();

break;

case "Visual Basic":

provider = new VBCodeProvider();

break;

case "JScript":

provider = new JScriptCodeProvider();

break;

default:

provider = new CSharpCodeProvider();

break;

}

return provider;

}

public CodeDomExampleForm()

{

this.SuspendLayout();

this.label1.Location = new System.Drawing.Point(395, 20);

this.label1.Size = new Size(180, 22);

this.label1.Text = "Select a programming language:";

this.comboBox1.Location = new System.Drawing.Point(560, 16);

this.comboBox1.Size = new Size(190, 23);

this.comboBox1.Name = "comboBox1";

this.comboBox1.Items.AddRange( new string[] { "CSharp", "Visual Basic", "JScript" } );

this.comboBox1.Anchor = System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right | System.Windows.Forms.AnchorStyles.Top;

this.comboBox1.SelectedIndex = 0;

this.generate_button.Location = new System.Drawing.Point(8, 16);

this.generate_button.Name = "generate_button";

this.generate_button.Size = new System.Drawing.Size(120, 23);

this.generate_button.Text = "Generate Code";

this.generate_button.Click += new System.EventHandler(this.generate_button_Click);

this.compile_button.Location = new System.Drawing.Point(136, 16);

this.compile_button.Name = "compile_button";

this.compile_button.Size = new System.Drawing.Size(120, 23);

this.compile_button.Text = "Compile";

this.compile_button.Click += new System.EventHandler(this.compile_button_Click);

this.run_button.Enabled = false;

this.run_button.Location = new System.Drawing.Point(264, 16);

this.run_button.Name = "run_button";

this.run_button.Size = new System.Drawing.Size(120, 23);

this.run_button.Text = "Run";

this.run_button.Click += new System.EventHandler(this.run_button_Click);

this.textBox1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)

| System.Windows.Forms.AnchorStyles.Left)

| System.Windows.Forms.AnchorStyles.Right);

this.textBox1.Location = new System.Drawing.Point(8, 48);

this.textBox1.Multiline = true;

this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;

this.textBox1.Name = "textBox1";

this.textBox1.Size = new System.Drawing.Size(744, 280);

this.textBox1.Text = "";

// CodeDomExampleForm

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(768, 340);

this.MinimumSize = new System.Drawing.Size(750, 340);

this.Controls.AddRange(new System.Windows.Forms.Control[] { this.textBox1, this.run_button, this.compile_button, this.generate_button, this.comboBox1, this.label1 });

this.Name = "CodeDomExampleForm";

this.Text = "CodeDom Hello World Example";

this.ResumeLayout(false);

}

protected override void Dispose( bool disposing )

{

base.Dispose( disposing );

}

private void InitializeComponent()

{

this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

this.ClientSize = new System.Drawing.Size(448, 269);

this.Name = "CodeDomExampleForm";

}

[STAThread]

static void Main()

{

Application.Run(new CodeDomExampleForm());

}

}

public class CodeDomExample

{

public static CodeCompileUnit BuildHelloWorldGraph()

{

//建立一个代码容器

//CodeCompileUnit 包含以下几个集合:可以存储包含 CodeDOM 源代码图形的 CodeNamespace 对象的集合、

//项目引用的程序集的集合,以及项目程序集的属性集合。

CodeCompileUnit CompileUnit = new CodeCompileUnit();

// 声明一个名称空间

CodeNamespace MySample = new CodeNamespace("MySample");

// 将名称空间加入到代码容器

CompileUnit.Namespaces.Add( MySample );

// 导入一个名称空间

MySample.Imports.Add( new CodeNamespaceImport("System") );

// 声明一个类型

CodeTypeDeclaration Hello = new CodeTypeDeclaration("Hello");

// 将类型加入到容器的类型集合中

MySample.Types.Add(Hello);

// 构造函数(并非必须)

CodeConstructor con = new CodeConstructor();

con.Attributes = MemberAttributes.Public | MemberAttributes.Final;

Hello.Members.Add(con);

// 表示可执行文件的入口点方法,也就是一个程序的入口

CodeEntryPointMethod Start = new CodeEntryPointMethod();

// 建立一个代码调用的表达式

CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(

// 调用方法. System.Console.WriteLine

new CodeTypeReferenceExpression("System.Console"), "WriteLine",

// 给方法传一个基元数据类型的值

new CodePrimitiveExpression("Hello World!") );

// 将方法加入到方法中

Start.Statements.Add(new CodeExpressionStatement(cs1));

CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression();

CodeMethodReferenceExpression cmr=new CodeMethodReferenceExpression();

cmr.MethodName="SayHell";

cs2.Method=cmr;

Start.Statements.Add(new CodeExpressionStatement(cs2));

// 将方法加入到类型中

Hello.Members.Add( Start );

// 成员函数SayHello,有参数,无返回值

// public bool SayHello(string input)

// {

// Console.WriteLine(input);

// return false;

// }

CodeMemberMethod cm = new CodeMemberMethod();

cm.Name = "SayHello";

cm.ReturnType=new CodeTypeReference(typeof(bool));

cm.Attributes = MemberAttributes.Public | MemberAttributes.Final|MemberAttributes.Static;

cm.Parameters.Add(

new CodeParameterDeclarationExpression(

typeof(string),"input"));

cm.Statements.Add(

new CodeMethodInvokeExpression(

new CodeSnippetExpression("Console"),"WriteLine",

new CodeArgumentReferenceExpression("input")));

cm.Statements.Add(new CodeMethodReturnStatement( new CodePrimitiveExpression(false)));

Hello.Members.Add(cm);

return CompileUnit;

}

public static void GenerateCode(CodeDomProvider provider, CodeCompileUnit compileunit)

{

//获得生成代码的接口

ICodeGenerator gen = provider.CreateGenerator();

// 输出到文件

IndentedTextWriter tw = new IndentedTextWriter(new StreamWriter("MyHello.cs", false), " ");

// 使用代码生成接口产生源代码.

gen.GenerateCodeFromCompileUnit(compileunit, tw, new CodeGeneratorOptions());

tw.Close();

}

public static CompilerResults CompileCode(CodeDomProvider provider, string filepath)

{

// 获得编译器.

ICodeCompiler compiler = provider.CreateCompiler();

//配置编译参数。将SYSTEM。DLL引用进来,同时明确生成的代码为EXE

CompilerParameters cp = new CompilerParameters(new string[] {"System.dll"}, filepath.Substring(0, filepath.LastIndexOf(".")+1)+"exe", false);

cp.GenerateExecutable = true;

// 调用编译器

CompilerResults cr = compiler.CompileAssemblyFromFile(cp, filepath);

return cr;

}

}

}

上面的代码还有一点没实现。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有