65.9K
CodeProject is changing. Read more.
Home

Compiling with CodeDom

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.48/5 (19 votes)

May 20, 2004

2 min read

viewsIcon

131505

downloadIcon

2304

This article explains how to compile code written in VB.NET or C# using the CodeDom.

Introduction

With the code of this article, you will compile code without having Visual Studio .NET installed, and you will avoid using the tangled compiler command line. With this code, you can create your own compiling environment.

I try to explain in this article how to dynamically compile code in VB.NET or C# using CodeDom technology. This technology simplifies the automatic code generation and can be used like a new generation of script engine, because you can write any .NET code, compile, and execute it in a dynamic way.

Background

What is CodeDom?

CodeDom is Code Document Object Model. This provides a graphical (in the sense of graph nodes, not of a picture) representation of code in the form of a tree. This represents the hierarchy of nested code elements (namespaces contain classes, classes contain methods, methods contain variable declarations, and so on). You can use CodeDom for generating an in memory code tree, or you can use it to compile ordinary code written in a file (like we will do later). View MSDN to read all about CodeDom elements. With this code tree, you can represent any piece of code independently of a specific language.

Using the code

In this section, we will create a class named VBNetCompiler. This class contains all the needed elements to compile Visual Basic .NET code files. I want to remember you that CodeDom is language-agnostic, and for this reason, you can easily create a CSharpCompiler or any compiler supported by CodeDom technology.

Imports section

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

Class and private members section

  • mFilesToCompile: Collection that contains all source code files.
  • mImportedDlls: Collection with all DLLs referenced by the code files.
  • mVBCompilerResults: This is an object in the CodeDom namespace to hold the output yielded by the compiler. This is similar to compiler output written in Output Pane of Visual Studio.
  • mVBCompilerErrors: Error collection produced by the Compiler
  • mVBCompilerParameters: This object is used to set the Compiler options
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 and public properties

   ''' 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

Compile function

This function is the core of the class. First, create a VBCodeProvider, this object provides the code generator object and the code compiler (we will use this object to compile the code). In the line oVBCodeCompiler = oVBCodeProvider.CreateCompiler, we create the code compiler. After creating the compiler, I assign the referenced assemblies needed for code compilation. Later, I add the files to compile, and call the method CompileAssemblyFromFileBatch that compiles the code file array with the parameters specified by mVBCompilerParameters object. The next lines write the compiler output to the 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

Comments

With this code, you will create a VBNet compiler, but you can create a CSharpCodeProvider instead of a VBCodeProvider and compile C# code.

This class is a simple example of CodeDom power, but this namespace is huge and has powerful and very interesting capabilities for code generation.