65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 CodeDom 编译

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.48/5 (19投票s)

2004年5月20日

2分钟阅读

viewsIcon

133022

downloadIcon

2304

本文介绍如何使用 CodeDom 编译用 VB.NET 或 C# 编写的代码。

引言

通过本文的代码,您无需安装 Visual Studio .NET 即可编译代码,并且可以避免使用繁琐的编译器命令行。 使用此代码,您可以创建自己的编译环境。

我试图在本文中解释如何使用 CodeDom 技术以动态方式编译 VB.NET 或 C# 代码。 此技术简化了自动代码生成,可以像新一代的脚本引擎一样使用,因为您可以编写任何 .NET 代码,编译并以动态方式执行它。

背景

什么是 CodeDom?

CodeDom 是 Code Document Object Model(代码文档对象模型)。它以树的形式提供代码的图形(在图节点意义上,而不是图片)表示。 这表示嵌套代码元素的层次结构(命名空间包含类,类包含方法,方法包含变量声明等等)。 您可以使用 CodeDom 生成内存中的代码树,也可以使用它来编译文件中编写的普通代码(就像我们稍后要做的那样)。 查看 MSDN 以阅读有关 CodeDom 元素的所有信息。 使用此代码树,您可以独立于特定语言表示任何代码段。

使用代码

在本节中,我们将创建一个名为 VBNetCompiler 的类。 此类包含编译 Visual Basic .NET 代码文件所需的所有元素。 我想提醒您,CodeDom 与语言无关,因此,您可以轻松地创建 CSharpCompiler 或 CodeDom 技术支持的任何编译器。

Imports 节

Imports System.IO
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.Collections.Specialized

类和私有成员节

  • mFilesToCompile:包含所有源代码文件的集合。
  • mImportedDlls:包含代码文件引用的所有 DLL 的集合。
  • mVBCompilerResults:这是 CodeDom 命名空间中的一个对象,用于保存编译器产生的输出。 这类似于 Visual Studio 输出窗格中编写的编译器输出。
  • mVBCompilerErrors:编译器产生的错误集合
  • mVBCompilerParameters:此对象用于设置编译器选项
Public Class VBNetCompiler

   'Files to compile
   Protected mFilesToCompile As New _
     System.Collections.Specialized.StringCollection

   'Referenced assemblies
   Protected mImportedDlls As New StringCollection

   'Compiler output
   Protected mVBCompilerResults As CompilerResults
   'Compiler errors
   Protected mVBCompilerErrors As CompilerErrorCollection
   'Compiler parameters
   Protected mVBCompilerParameters As New CompilerParameters

构造函数和公共属性

   ''' Constructor
   Public Sub New(ByVal ParamArray pFilesToCompile() As String)
      mFilesToCompile = New System.Collections.Specialized.StringCollection
      For Each oFile As String In pFilesToCompile
         mFilesToCompile.Add(oFile)
      Next
   End Sub

   ''' Constructor
   Public Sub New()
   End Sub

   ''' Files to compile
   Public Property FilesToCompile() As _
         System.Collections.Specialized.StringCollection
      Get
         Return mFilesToCompile
      End Get
      Set(ByVal Value As System.Collections.Specialized.StringCollection)
         mFilesToCompile = Value
      End Set
   End Property

   ''' Compiler parameters
   Public Property VBCompilerParameters() As CompilerParameters
      Get
         Return mVBCompilerParameters
      End Get
      Set(ByVal Value As CompilerParameters)
         mVBCompilerParameters = Value
      End Set
   End Property

   ''' Compiler errors
   Public ReadOnly Property VBCompilerErrors() As CompilerErrorCollection
      Get
         Return mVBCompilerErrors
      End Get
   End Property

   ''' Compiler output
   Public ReadOnly Property VBCompilerResults() As CompilerResults
      Get
         Return mVBCompilerResults
      End Get
   End Property


   ''' Referenced assemblies
   Public Property ImportedDlls() As StringCollection
      Get
         Return mImportedDlls
      End Get
      Set(ByVal Value As StringCollection)
         mImportedDlls = Value
      End Set
   End Property

编译函数

此函数是该类的核心。 首先,创建一个 VBCodeProvider,此对象提供代码生成器对象和代码编译器(我们将使用此对象来编译代码)。 在行 oVBCodeCompiler = oVBCodeProvider.CreateCompiler 中,我们创建了代码编译器。 创建编译器后,我分配代码编译所需的引用程序集。 稍后,我添加要编译的文件,并调用 CompileAssemblyFromFileBatch 方法,该方法使用 mVBCompilerParameters 对象指定的参数编译代码文件数组。 接下来的行将编译器输出写入 Console

   ''' Compiles the code
   Public Function Compile() As CompilerResults
      Dim oVBCodeProvider As New VBCodeProvider
      Dim oVBCodeCompiler As ICodeCompiler
      Dim oVBCompilerResults As CompilerResults
      Dim oVBCompilerError As CompilerError

      oVBCodeCompiler = oVBCodeProvider.CreateCompiler

      With mVBCompilerParameters
         With .ReferencedAssemblies
            For Each oDll As String In mImportedDlls
               ' adds assembly reference
               .Add(oDll)
            Next
         End With
      End With

      'Compiling process
      Dim oFiles() As String
      ReDim oFiles(mFilesToCompile.Count - 1)
      mFilesToCompile.CopyTo(oFiles, 0)
      oVBCompilerResults = _
       oVBCodeCompiler.CompileAssemblyFromFileBatch(mVBCompilerParameters, _
       oFiles)


      mVBCompilerResults = oVBCompilerResults
      With oVBCompilerResults
         Console.WriteLine("---------------------------------")
         Console.WriteLine("COMPILER OUTPUT: ")
         Console.WriteLine("---------------------------------")
         For Each oOut As String In .Output
            Console.WriteLine(oOut)
         Next
      End With

      With oVBCompilerResults
         Console.WriteLine("---------------------------------")
         Console.WriteLine("COMPILER ERRORS: " & .Errors.Count)
         Console.WriteLine("---------------------------------")

         mVBCompilerErrors = .Errors
         Dim ErrorLog As String
         For Each oVBCompilerError In .Errors
            ErrorLog += oVBCompilerError.ToString & vbNewLine
            Console.WriteLine(oVBCompilerError.ToString)
         Next
         If .Errors.Count > 0 Then
          Throw New Exception("The compiler has thrown the following errors:" & _
                 vbNewLine & ErrorLog)
         End If
      End With

      Return oVBCompilerResults
   End Function

End Class

注释

使用此代码,您将创建一个 VBNet 编译器,但您可以创建一个 CSharpCodeProvider 而不是 VBCodeProvider 并编译 C# 代码。

此类是 CodeDom 威力的一个简单示例,但是此命名空间非常庞大,并且具有用于代码生成的强大而有趣的强大功能。

© . All rights reserved.