locked
Code Compilation at Runtime? RRS feed

  • Question

  • Is it possible to write a program that generates code at runtime, then compiles it into a DLL?
    Friday, February 9, 2007 11:03 PM

Answers

  • Yes, you can. Remember, every computer (with the .NET framework) has access to the compiler engine. Even so, there's a specific namespace which you can use:

    Microsoft.VisualBasic.VBCodeProvider

    Look that up: there's a ton of help, and a few examples.

    Saturday, February 10, 2007 1:04 PM
  • Try this sample program :-)

    Public
    Shared Function CompileExecutable(sourceName As String) As Boolean
    Dim sourceFile As FileInfo = New FileInfo(sourceName)
    Dim provider As CodeDomProvider = Nothing
    Dim compileOk As Boolean = False

    ' Select the code provider based on the input file extension.
    If sourceFile.Extension.ToUpper(CultureInfo.InvariantCulture) = ".CS"

    provider = New Microsoft.CSharp.CSharpCodeProvider()

    ElseIf sourceFile.Extension.ToUpper(CultureInfo.InvariantCulture) = ".VB"

    provider = New Microsoft.VisualBasic.VBCodeProvider()

    Else
    Console.WriteLine("Source file must have a .cs or .vb extension")
    End If

    If Not provider Is Nothing

    ' Format the executable file name.
    ' Build the output assembly path using the current directory
    ' and <source>_cs.exe or <source>_vb.exe.

    Dim exeName As String = String.Format("{0\{1.exe", _
    System.Environment.CurrentDirectory, _
    sourceFile.Name.Replace(".", "_"))

    Dim cp As CompilerParameters = new CompilerParameters()

    ' Generate an executable instead of
    ' a class library.
    cp.GenerateExecutable = True

    ' Specify the assembly file name to generate.
    cp.OutputAssembly = exeName

    ' Save the assembly as a physical file.
    cp.GenerateInMemory = False

    ' Set whether to treat all warnings as errors.
    cp.TreatWarningsAsErrors = False

    ' Invoke compilation of the source file.
    Dim cr As CompilerResults = provider.CompileAssemblyFromFile(cp, _
    sourceName)

    If cr.Errors.Count > 0
    ' Display compilation errors.
    Console.WriteLine("Errors building {0 into {1", _
    sourceName, cr.PathToAssembly)

    Dim ce As CompilerError
    For Each ce In cr.Errors
    Console.WriteLine(" {0", ce.ToString())
    Console.WriteLine()
    Next ce
    Else
    ' Display a successful compilation message.
    Console.WriteLine("Source {0 built into {1 successfully.", _
    sourceName, cr.PathToAssembly)
    End If

    ' Return the results of the compilation.
    If cr.Errors.Count > 0
    compileOk = False
    Else
    compileOk = True
    End If
    End If
    return compileOk

    End Function
    Saturday, February 10, 2007 6:27 PM
  • The property GenerateExecutable Set to FALSE will compile to a class library.
    The help explains a lot of the methods and functionality: play with it a bit.



    Sunday, February 11, 2007 12:05 AM

All replies

  • Yes, you can. Remember, every computer (with the .NET framework) has access to the compiler engine. Even so, there's a specific namespace which you can use:

    Microsoft.VisualBasic.VBCodeProvider

    Look that up: there's a ton of help, and a few examples.

    Saturday, February 10, 2007 1:04 PM
  • Thank you! That's exactly what I was looking for.

    Now... How do I create a resource from a PNG image and compile that?

    Saturday, February 10, 2007 6:07 PM
  • Try this sample program :-)

    Public
    Shared Function CompileExecutable(sourceName As String) As Boolean
    Dim sourceFile As FileInfo = New FileInfo(sourceName)
    Dim provider As CodeDomProvider = Nothing
    Dim compileOk As Boolean = False

    ' Select the code provider based on the input file extension.
    If sourceFile.Extension.ToUpper(CultureInfo.InvariantCulture) = ".CS"

    provider = New Microsoft.CSharp.CSharpCodeProvider()

    ElseIf sourceFile.Extension.ToUpper(CultureInfo.InvariantCulture) = ".VB"

    provider = New Microsoft.VisualBasic.VBCodeProvider()

    Else
    Console.WriteLine("Source file must have a .cs or .vb extension")
    End If

    If Not provider Is Nothing

    ' Format the executable file name.
    ' Build the output assembly path using the current directory
    ' and <source>_cs.exe or <source>_vb.exe.

    Dim exeName As String = String.Format("{0\{1.exe", _
    System.Environment.CurrentDirectory, _
    sourceFile.Name.Replace(".", "_"))

    Dim cp As CompilerParameters = new CompilerParameters()

    ' Generate an executable instead of
    ' a class library.
    cp.GenerateExecutable = True

    ' Specify the assembly file name to generate.
    cp.OutputAssembly = exeName

    ' Save the assembly as a physical file.
    cp.GenerateInMemory = False

    ' Set whether to treat all warnings as errors.
    cp.TreatWarningsAsErrors = False

    ' Invoke compilation of the source file.
    Dim cr As CompilerResults = provider.CompileAssemblyFromFile(cp, _
    sourceName)

    If cr.Errors.Count > 0
    ' Display compilation errors.
    Console.WriteLine("Errors building {0 into {1", _
    sourceName, cr.PathToAssembly)

    Dim ce As CompilerError
    For Each ce In cr.Errors
    Console.WriteLine(" {0", ce.ToString())
    Console.WriteLine()
    Next ce
    Else
    ' Display a successful compilation message.
    Console.WriteLine("Source {0 built into {1 successfully.", _
    sourceName, cr.PathToAssembly)
    End If

    ' Return the results of the compilation.
    If cr.Errors.Count > 0
    compileOk = False
    Else
    compileOk = True
    End If
    End If
    return compileOk

    End Function
    Saturday, February 10, 2007 6:27 PM
  • Thanks, that code will come in really useful.

    But 2 questions remain unanswered:

    1. How do I compile to a DLL intead of an EXE?
    2. How do I add a PNG resource?
    Saturday, February 10, 2007 6:35 PM
  • I worked part 2 out:

    System.CodeDom.Compiler.CompilerParameters.EmbeddedResources.Add("icon.png")

    Saturday, February 10, 2007 6:38 PM
  • The property GenerateExecutable Set to FALSE will compile to a class library.
    The help explains a lot of the methods and functionality: play with it a bit.



    Sunday, February 11, 2007 12:05 AM
  • Thanks for all your help.
    Sunday, February 11, 2007 1:08 PM
  • This post is really useful, but it still missing something
    How i call this ressource in the source code to compile??
     the compiler refuse My.ressources.name
    Thursday, July 5, 2007 1:51 PM