zoukankan      html  css  js  c++  java
  • CodeDom系列五动态编译

            继上节我们把Code 表达式编译成为了Code代码,有时我们只想动态编译程序集,在内存中或者是

    硬盘上调用,这就是CodeDom的动态编译。微软在CodeDom中提供了动态编译程序,这是ICodeComp

    iler的用武之地了,它定义用于调用源代码编译的接口或使用指定编译器的 CodeDOM 树。可以从CodeDomProvider生成引用对象:CodeDomProvider.CreateProvider("").CreateCompiler();

          在ICodeCompiler中为我们提供了程序集编译的方法有:
                CompileAssemblyFromDom :使用指定的编译器设置从指定的 CodeCompileUnit 所包含的 System.CodeDom 树中编译程序集。
                CompileAssemblyFromDomBatch:基于包含在 CodeCompileUnit 对象的指定数组中的 System.CodeDom 树,使用指定的编译器设置编译程序集。 
                CompileAssemblyFromFile:从包含在指定文件中的源代码,使用指定的编译器设置编译程序集。 
                CompileAssemblyFromFileBatch:从包含在指定文件中的源代码,使用指定的编译器设置编译程序集。 
                CompileAssemblyFromSource: 从包含源代码的指定字符串,使用指定的编译器设置编译程序集。
                CompileAssemblyFromSourceBatch:从包含源代码的字符串的指定数组,使用指定的编译器设置编译程序集。

    在我们的CodeDomProvider也提供了CompileAssemblyFromDom、CompileAssemblyFromFile、CompileAssemblyFromSource。

           在他们的编译时候都有一个变异参数CompilerParameters,提供了编译时参数选项:
    CompilerOptions:获取或设置调用编译器时使用的可选附加命令行参数字符串。
    EmbeddedResources:获取要在编译程序集输出时包含的 .NET Framework 资源文件。
    Evidence:指定一个证据对象,该对象表示要授予已编译的程序集的安全策略权限。
    GenerateExecutable:获取或设置一个值,该值指示是否生成可执行文件。
    GenerateInMemory:获取或设置一个值,该值指示是否在内存中生成输出。
    IncludeDebugInformation:获取或设置一个值,该值指示是否在已编译的可执行文件中包含调试信息。
    LinkedResources:获取当前源中引用的 .NET Framework 资源文件。
    MainClass:获取或设置主类的名称。
    OutputAssembly:获取或设置输出程序集的名称。
    ReferencedAssemblies:获取当前项目所引用的程序集。
    TempFiles:获取或设置包含临时文件的集合.
    TreatWarningsAsErrors:获取或设置一个值,该值指示是否将警告视为错误。
    UserToken:获取或设置在创建编译器进程时使用的用户标记。
    WarningLevel:获取或设置使编译器中止编译的警告级别。
    Win32Resource:获取或设置要链接到已编译程序集中的 Win32 资源文件的文件名。

    他们的结果返回编译结果CompilerResults,提供了编译结果信息:
    CompiledAssembly:获取或设置已编译的程序集。
    Errors:获取编译器错误和警告的集合。
    Evidence:指示证据对象,该对象表示编译的程序集的安全策略权限。
    NativeCompilerReturnValue:获取或设置编译器的返回值。
    Output:获取编译器输出消息。
    PathToAssembly:获取或设置已编译程序集的路径。
    TempFiles:获取或设置要使用的临时文件集合。

    下面我们就来的Demo:实现简单的HelloWord编译:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    namespace CodeDomDemo4
    {
    class Program
    {
    static void Main(string[] args)
    {
    Program pro = new Program();
    CodeCompileUnit unit= pro.CodeDomHelloDemo();
    Console.WriteLine(pro.GenerateCode(unit, "c#"));
    Console.WriteLine(pro.GenerateCode(unit, "vb"));
    CompilerResults result=  pro.CompilerCode(unit, "c#");
    if (result.Errors != null)
    {
    foreach (var item in result.Errors)
    {
    Console.WriteLine(item);
    }
    }
    Console.Read();
    }
    public string GenerateCode(CodeCompileUnit unit, string language)
    {
    StringBuilder sb = new StringBuilder();
    System.IO.StringWriter sw = new System.IO.StringWriter();
    CodeDomProvider.CreateProvider(language).GenerateCodeFromCompileUnit
    (unit, sw,null);
    sw.Close();
    return sw.ToString();
    }
    public CompilerResults CompilerCode(CodeCompileUnit unit, string language)
    {
    CompilerParameters option = new CompilerParameters();
    option.GenerateExecutable = true;
    option.GenerateInMemory = false;
    option.IncludeDebugInformation = true;
    option.ReferencedAssemblies.Add("System.dll");
    option.OutputAssembly = "Demo5.exe";
    return CodeDomProvider.CreateProvider(language).CompileAssemblyFromDom
    (option,unit);
    }
    public CodeCompileUnit  CodeDomHelloDemo()
    {
    //Mehtod
    CodeEntryPointMethod method = new CodeEntryPointMethod();
    //Console.WriteLine("Hello Word!");
    CodeMethodInvokeExpression methodWrite = new CodeMethodInvokeExpression(
    new CodeTypeReferenceExpression(typeof(Console)), "WriteLine", 
    new CodePrimitiveExpression("Hello Word!"));
    //Console.Read();
    CodeMethodInvokeExpression methodread = new CodeMethodInvokeExpression(
    new CodeTypeReferenceExpression(typeof(Console)), "Read");
    method.Statements.Add(methodWrite);
    method.Statements.Add( methodread);
    //class Hello
    CodeTypeDeclaration hello = new CodeTypeDeclaration("Hello");
    hello.Attributes = MemberAttributes.Public;
    hello.Members.Add(method);
    //namespace Demo5
    CodeNamespace nspace = new CodeNamespace("Demo5");
    nspace.Imports.Add(new CodeNamespaceImport("System"));
    nspace.Types.Add(hello);
    //CodeCompileUnit
    CodeCompileUnit unit = new CodeCompileUnit();
    unit.Namespaces.Add(nspace);
    return unit;
    }
    }
    }

    输出代码为:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     此代码由工具生成。
    //     运行时版本:2.0.50727.4927
    //
    //     对此文件的更改可能会导致不正确的行为,并且如果
    //     重新生成代码,这些更改将会丢失。
    // </auto-generated>
    //------------------------------------------------------------------------------
    namespace Demo5 {
    using System;
    public class Hello {
    public static void Main() {
    System.Console.WriteLine("Hello Word!");
    System.Console.Read();
    }
    }
    }
    '------------------------------------------------------------------------------
    ' <auto-generated>
    '     此代码由工具生成。
    '     运行时版本:2.0.50727.4927
    '
    '     对此文件的更改可能会导致不正确的行为,并且如果
    '     重新生成代码,这些更改将会丢失。
    ' </auto-generated>
    '------------------------------------------------------------------------------
    Option Strict Off
    Option Explicit On
    Imports System
    Namespace Demo5
    Public Class Hello
    Public Shared Sub Main()
    System.Console.WriteLine("Hello Word!")
    System.Console.Read
    End Sub
    End Class
    End Namespace
    在bin/debug下有生成Demo5.exe和Demo5.pdb文件:
    image
    点击Demo5.exe运行视图:
    image
    今天就写到这里,睡觉了。CodeDom很简单,要了解的东西并不多。下面如果有机会就写几个示例Demo,
    暂时考虑自动生成一些算法Code, 没有实际意义,或者是做个类编译器。 欢迎大家指正,共同学习共同进步。


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    浅谈SQLite——查询处理及优化
    .NET 并行(多核)编程系列之七 共享数据问题和解决概述
    sql 存储过程学习一
    SQL中获得EXEC后面的sql语句或者存储过程的返回值的方法 【收藏】
    script刷新页面,刷新代码
    C#编程中关于数据缓存的经验总结
    SQL存储过程的概念,优点及语法
    SQLite数据库安装、试用及编程测试手记
    c# sqlite 数据库加密
    进销存管理系统的设计与实现
  • 原文地址:https://www.cnblogs.com/whitewolf/p/1771868.html
Copyright © 2011-2022 走看看