使用 CodeDom 编译






4.48/5 (19投票s)
2004年5月20日
2分钟阅读

133022

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 威力的一个简单示例,但是此命名空间非常庞大,并且具有用于代码生成的强大而有趣的强大功能。