`
love19820823
  • 浏览: 954448 次
文章分类
社区版块
存档分类
最新评论

使用CODEDOM

 
阅读更多

前一阶段一直在做一个基于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;
}
}

}

分享到:
评论

相关推荐

    codeDom

    总的来说,这个压缩包可能包含了一个使用CodeDom进行动态代码生成和编译的.NET项目,项目可能涉及Windows Forms应用、VSA脚本支持以及动态生成的源代码。CodeDom的强大之处在于其灵活性和跨语言性,使得开发更加便捷...

    C# 使用 CodeDom 动态创建应用程序

    .NET 提供了一个System.CodeDom的命名空间,它允许用户动态编译和创建程序集。本文提供了有关如何动态创建程序集的内容。 用途 1、模板化代码生成:生成适用于 ASP.NET、XML Web 服务客户端代理、代码向导、设计器或...

    使用CodeDom转换WinForms => Web窗体

    本文将深入探讨如何使用CodeDom技术将基于Windows的WinForms应用程序转换为ASP.NET Web窗体,这对于那些希望将桌面应用扩展到网络环境的开发者来说尤其有价值。 Windows Forms(WinForms)是.NET框架中用于构建桌面...

    CodeDom摘要介绍

    1. **易于使用**:使用 CodeDom 编写代码生成器更加直观且容易维护。 2. **功能封装**:CodeDom 将许多常用的功能进行了封装,如添加导入语句、定义命名空间等,这些都可以通过简单的步骤实现。 3. **多语言支持**:...

    CodeDom代码生成工具(源码)

    例如,要使用CodeDom生成一个简单的C#类,你可以首先创建一个`CodeCompileUnit`对象,然后添加一个`CodeNamespace`,接着在命名空间中添加`CodeTypeDeclaration`表示类,最后在类中添加`CodeMemberMethod`表示方法。...

    使用CodeDom编译和运行VB.NET代码

    本文将深入探讨如何使用CodeDom来编译和运行VB.NET代码,以及在Windows和Visual Studio开发环境中如何应用这一技术。 首先,你需要导入必要的命名空间: ```csharp using System; using System.CodeDom.Compiler; ...

    Nyan-Compiler:使用Codedom的C#和VB.NET的基本IDE编译器

    **Nyan-Compiler:使用Codedom的C#和VB.NET基本IDE编译器** Nyan-Compiler是一款基于C#和VB.NET编程语言的简单集成开发环境(IDE),利用了.NET框架中的CodeDOM(代码对象模型)技术。CodeDOM是一个强大的工具,...

    Generation_Database_by_NHibernate_and_CodeDOM

    3. **CodeDOM使用**:掌握CodeDOM的API,如`CodeCompileUnit`、`CodeNamespace`、`CodeTypeDeclaration`等,用于构建代码结构。 4. **数据库反向工程**:了解如何从现有数据库中提取表结构信息,作为生成代码的基础...

    codeDOM动态创建类及反射使用的小例子

    这提供了一个直观的演示,展示了CodeDOM和反射在实际应用中的结合使用。 总结来说,CodeDOM和反射是C#编程中非常强大的工具。CodeDOM让我们能够动态地生成和修改代码,而反射则让我们在运行时能够访问和操作类型...

    C#_.NET_动态调用webservice的三种方式

    使用ServiceDescriptionImporter类创建和格式化WSDL文档文件后,我们可以使用CodeDom动态创建客户端代理类程序集。我们可以使用System.CodeDom命名空间中的CodeCompileUnit类来创建客户端代理类程序集。 第四步:...

    CodeDOM Go Kit:CodeDOM已死,CodeDOM万岁

    "CodeDOM Go Kit:CodeDOM已死,CodeDOM万岁"这个标题可能暗示了一个关于CodeDOM的新工具或库,它可能改进了CodeDOM的一些不足,或者提供了更高效的使用方式。 CodeDOM最初设计用于支持多种编程语言,如VB.NET和C#...

    动态调用WebService(C#)

    本文将深入探讨如何实现这个功能,涉及的关键技术包括反射、CodeDom、编程使用C#编译器以及WebService本身。 首先,反射(Reflection)是.NET框架的一个重要特性,它允许程序在运行时检查自身的信息,如类型、成员...

    CodeDom示例(c#)

    CodeDom,全称为Code Document Object Model,是.NET框架中用于生成和编译源代码的抽象语法树(AST)表示。这个技术主要应用于自动化代码生成、动态类型创建以及元编程等场景。在C#中,CodeDom提供了一组类库,如`...

    动态生成与编译

    为了更好地理解和使用CodeDOM,我们可以通过一个简单的示例来展示其基本用法: ```csharp using System; using System.CodeDom; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.IO; using ...

    C#代码动态编译、动态执行、动态调试[参照].pdf

    在.NET框架中,我们可以使用CodeDOM来实现动态编译。CodeDOM提供了一个编译器,可以将C#代码编译成IL代码。我们可以使用CodeCompileUnit来编译C#代码,生成动态代码。 在动态编译中,我们可以指定编译参数,例如:...

    CodeDom

    CodeDom //Console.WriteLine("Test0: {0}", Evaluator.EvaluateToInteger("(30 + 4) * 2")); //Console.WriteLine("Test1: {0}", Evaluator.EvaluateToString(@"""Hello "" + ""There""")); //Console....

    RoslynCodeDomProvider:Roslyn CodeDOM提供程序

    介绍使用新的.NET编译器平台(“ Roslyn”)编译器作为服务API的替换CodeDOM提供程序。 这为使用CodeDOM的系统中的新语言功能(例如ASP.NET运行时编译)提供了支持,并提高了这些系统的编译性能。 有关Microsoft....

Global site tag (gtag.js) - Google Analytics