C++/CLI Code Snippet - Compile C# or VB source code run-time

C++/CLI Code Snippet - Compile C# or VB source code run-time

C++/CLI Code Snippet - Compile C# or VB source code run-time

C++/CLI code snippet compile C# or VB source code run-time from a text string or external text file and build the executable. Programmatically compile code using C#/VB compiler.

Bookmark:

C++/CLI Code Snippet - Compile C# or VB source code run-time

This .Net C++/CLI code snippet compile C# or VB source code runtime from a text string or external text file and build the executable. To use this function simply provide language (C#/VB) provider, source code in text string or as a file, output executable file name (optional), output assembly name (optional), resource files (optional), reference string to get errors.

The .NET Framework exposes classes that allow you to programmatically access the C# and VB language compilers. This might be useful if you want to write your own code-compiling utilities. This code snippet provides sample code that enables you to compile code from a text string or external text file. The code snippet allows you to build the executable. Any errors that occur during the compilation process are return as a string.

bool CompileCode(System::CodeDom::Compiler::CodeDomProvider ^_CodeProvider, System::String ^_SourceCode, System::String ^_SourceFile, System::String ^_ExeFile, System::String ^_AssemblyName, array<System::String^> ^_ResourceFiles, System::String ^%_Errors)
{
    // set interface for compilation
    System::CodeDom::Compiler::ICodeCompiler ^_CodeCompiler = _CodeProvider->CreateCompiler();

    // Define parameters to invoke a compiler
    System::CodeDom::Compiler::CompilerParameters ^_CompilerParameters = gcnew System::CodeDom::Compiler::CompilerParameters();

    if (_ExeFile != nullptr)
    {
        // Set the assembly file name to generate.
        _CompilerParameters->OutputAssembly = _ExeFile;

        // Generate an executable instead of a class library.
        _CompilerParameters->GenerateExecutable = true;
        _CompilerParameters->GenerateInMemory = false;
    }
    else if (_AssemblyName != nullptr)
    {
        // Set the assembly file name to generate.
        _CompilerParameters->OutputAssembly = _AssemblyName;

        // Generate an executable instead of a class library.
        _CompilerParameters->GenerateExecutable = false;
        _CompilerParameters->GenerateInMemory = false;
    }
    else
    {
        // Generate an executable instead of a class library.
        _CompilerParameters->GenerateExecutable = false;
        _CompilerParameters->GenerateInMemory = true;
    }


    // Generate debug information.
    //_CompilerParameters.IncludeDebugInformation = true;

    // Set the level at which the compiler 
    // should start displaying warnings.
    _CompilerParameters->WarningLevel = 3;

    // Set whether to treat all warnings as errors.
    _CompilerParameters->TreatWarningsAsErrors = false;

    // Set compiler argument to optimize output.
    _CompilerParameters->CompilerOptions = "/optimize";

    // Set a temporary files collection.
    // The TempFileCollection stores the temporary files
    // generated during a build in the current directory,
    // and does not delete them after compilation.
    _CompilerParameters->TempFiles = gcnew System::CodeDom::Compiler::TempFileCollection(".", true);

    if (_ResourceFiles != nullptr && _ResourceFiles->Length > 0)
        for each (System::String ^_ResourceFile in _ResourceFiles)
        {
            // Set the embedded resource file of the assembly.
            _CompilerParameters->EmbeddedResources->Add(_ResourceFile);
        }


    try
    {
        // Invoke compilation
        System::CodeDom::Compiler::CompilerResults ^_CompilerResults = nullptr;

        if (_SourceFile != nullptr && System::IO::File::Exists(_SourceFile))
            // soruce code in external file
            _CompilerResults = _CodeCompiler->CompileAssemblyFromFile(_CompilerParameters, _SourceFile);
        else
            // source code pass as a string
            _CompilerResults = _CodeCompiler->CompileAssemblyFromSource(_CompilerParameters, _SourceCode);

        if (_CompilerResults->Errors->Count > 0)
        {
            // Return compilation errors
            _Errors = "";
            for each (System::CodeDom::Compiler::CompilerError ^CompErr in _CompilerResults->Errors)
            {
                _Errors += "Line number " + CompErr->Line + ", Error Number: " + CompErr->ErrorNumber + ", '" + CompErr->ErrorText + ";\r\n\r\n";
            }

            // Return the results of compilation - Failed
            return false;
        }
        else
        {
            // no compile errors
            _Errors = nullptr;
        }
    }
    catch (Exception ^_Exception)
    {
        // Error occurred when trying to compile the code
        _Errors = _Exception->Message;
        return false;
    }

    // Return the results of compilation - Success
    return true;
}


Here is a simple example shows how to use above function (CompileCode) to compile a C# (C-Sharp) source code pass as a string, resulting executable file will be saved as C:\temp\ C-Sharp-test.exe

System::String ^_Errors = "";

// C# source code pass as a string
System::String ^_CSharpSourceCode = "                        using System;" + 
    "\r\n" + "\r\n" + "                        namespace test" + 
    "\r\n" + "                        {" + "\r\n" + 
    "                            class Program" + "\r\n" + 
    "                            {" + "\r\n" + 
    "                                static void Main(string[] args)" + 
    "\r\n" + "                                {" + "\r\n" + 
    "                                    Console.WriteLine(\"Press ENTER key to start ...\");" + 
    "\r\n" + "                                    Console.ReadLine();" + "\r\n" + 
    "                                    for (int c=0; c<=100; c++)" + 
    "\r\n" + "                                        Console.WriteLine(c.ToString());" + 
    "\r\n" + "                                }" + "\r\n" + 
    "                            }" + "\r\n" + 
    "                        }";

// Compile C-Sharp code
if (CompileCode(gcnew Microsoft::CSharp::CSharpCodeProvider, _CSharpSourceCode, nullptr, "c:\\temp\\C-Sharp-test.exe", nullptr, nullptr, _Errors))
    Console::WriteLine("Code compiled successfully");
else
    Console::WriteLine("Error occurred during compilation : \r\n" + _Errors);


This example shows how to use above function (CompileCode) to compile a VB (Visual Basic) source code pass as a string, resulting executable file will be saved as C:\temp\ C-Sharp-test.exe

System::String ^_Errors = "";

// VB source code pass as a string
System::String ^_VBSourceCode = "                        Imports System" + 
    "\r\n" + "\r\n" + "                        Namespace test" + "\r\n" + 
    "	                        Friend Class Program" + "\r\n" + 
    "		                        Shared Sub Main(ByVal args() As String)" + 
    "\r\n" + "			                        Console.WriteLine(\"Press ENTER key to start ...\")" + 
    "\r\n" + "			                        Console.ReadLine()" + "\r\n" + 
    "			                        For c As Integer = 0 To 100" + "\r\n" + 
    "				                        Console.WriteLine(c.ToString())" + 
    "\r\n" + "			                        Next c" + "\r\n" + 
    "		                        End Sub" + "\r\n" + 
    "	                        End Class" + "\r\n" + 
    "                        End Namespace";

// compile visual basic code
if (CompileCode(gcnew Microsoft::VisualBasic::VBCodeProvider(), _VBSourceCode, nullptr, "c:\\temp\\VB-test.exe", nullptr, nullptr, _Errors))
    Console::WriteLine("Code compiled successfully");
else
    Console::WriteLine("Error occurred during compilation : \r\n" + _Errors);


This example shows how to use above function (CompileCode) to compile a C# and VB source code from external files C#:c:\temp\test.cs and VB:c:\temp\test.vb, resulting executable files will be saved as C#:C:\temp\C-Sharp-test.exe and VB:C:\temp\VB-test.exe, and also shows how to run the executable after creating it using Process.Start.

// Compile C-Sharp code
if (CompileCode(gcnew Microsoft::CSharp::CSharpCodeProvider(), nullptr, "c:\\temp\\test.cs", "c:\\temp\\C-Sharp-test.exe", nullptr, nullptr, _Errors))
{
    Console::WriteLine("Code compiled successfully");
    // lets run the program
    System::Diagnostics::Process::Start("c:\\temp\\C-Sharp-test.exe");
}
else
    Console::WriteLine("Error occurred during compilation : \r\n" + _Errors);


// compile visual basic code
if (CompileCode(gcnew Microsoft::VisualBasic::VBCodeProvider(), nullptr, "c:\\temp\\test.vb", "c:\\temp\\VB-test.exe", nullptr, nullptr, _Errors))
    Console::WriteLine("Code compiled successfully");
else
    Console::WriteLine("Error occurred during compilation : \r\n" + _Errors);


C++/CLI Keywords Used:

  • System.CodeDom.Compiler
  • CodeDomProvider
  • CompilerResults
  • CompilerParameters
  • CompilerOptions
  • Exception

Code Snippet Information:

  • Applies To: Visual Studio, .Net, C++, CLI, VB, Visual Basic, Compiler, Microsoft.CSharp, Microsoft.VisualBasic, System.CodeDom.Compiler, Programmatically compile code, Run-Time Code Generation
  • Programming Language : C++/CLI

External Resources:

Leave a comment