How To Programmatically Compile Code Using C# Compiler (304655)



The information in this article applies to:

  • Microsoft .NET Framework 1.0, when used with:
    • Microsoft Visual C# .NET (2002)

This article was previously published under Q304655
For a Microsoft Visual Basic .NET version of this article, see 304654.

SUMMARY

The .NET Framework exposes classes that allow you to programmatically access the C# language compiler. This might be useful if you want to write your own code-compiling utilities. This article provides sample code that enables you to compile code from a text source. The application allows you to either just build the executable or build the executable and run it. Any errors that occur during the compilation process are displayed on the form.

MORE INFORMATION

Step 1: Requirements

  • Visual Studio .NET
  • Visual C# .NET language compiler

Step 2: How to Programmatically Compile Code

The .NET Framework provides the ICodeCompiler compiler execution interface. The CSharpCodeProvider class implements this interface and provides access to instances of the C# code generator and code compiler. The following sample code creates an instance of CSharpCodeProvider and uses it to get a reference to a ICodeCompiler interface.
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
				

Once you have a reference to an ICodeCompiler interface, you can use it to compile your source code. You will pass parameters to the compiler by using the CompilerParameters class. Here is an example:
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = icc.CompileAssemblyFromSource(parameters,SourceString);
				

The code above uses the CompilerParameters object to tell the compiler that you want to generate an executable file (as opposed to a DLL) and that you want to output the resulting assembly to disk. The call to CompileAssemblyFromSource is where the assembly gets compiled. This method takes the parameters object and the source code, which is a string. After you compile your code, you can check to see if there were any compilation errors. You use the return value from CompileAssemblyFromSource, which is a CompilerResults object. This object contains an errors collection, which contains any errors that occurred during the compile.
   if (results.Errors.Count > 0)
   {
    foreach(CompilerError CompErr in results.Errors)
    {
     textBox2.Text = textBox2.Text +
         "Line number " + CompErr.Line + 
         ", Error Number: " + CompErr.ErrorNumber + 
         ", '" + CompErr.ErrorText + ";" + 
         Environment.NewLine + Environment.NewLine;
    }
   }
				

There are other options for compiling, such as compiling from a file. You can also batch compile, which means you can compile multiple files or sources at the same time. Additional information on these classes can be found in the MSDN Online Library:

Step 3: Step-by-Step Procedure Example

  1. Create a new Visual C# .NET Windows application. Form1 is created by default.
  2. In the Code View of the Form1, replace the existing code with the following:
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.CodeDom;
    using System.CodeDom.Compiler;
    using Microsoft.CSharp;
    using System.Diagnostics;
    
    namespace CSWinCompiler
    {
       /// <summary>
       /// Summary description for Form1.
       /// </summary>
       public class Form1 : System.Windows.Forms.Form
       {
          private System.Windows.Forms.TextBox textBox1;
          private System.Windows.Forms.Button button1;
          private System.Windows.Forms.TextBox textBox2;
          private System.Windows.Forms.Button button2;
          /// <summary>
          /// Required designer variable.
          /// </summary>
          private System.ComponentModel.Container components = null;
    
          public Form1()
          {
             // 
             // Required for Windows Form Designer support
             // 
             InitializeComponent();
    
             // 
             // TODO: Add any constructor code after InitializeComponent call
             // 
          }
    
          /// <summary>
          /// Clean up any resources being used.
          /// </summary>
          protected override void Dispose( bool disposing )
          {
             if( disposing )
             {
                if (components != null) 
                {
                   components.Dispose();
                }
             }
             base.Dispose( disposing );
          }
    
          #region Windows Form Designer generated code
          /// <summary>
          /// Required method for Designer support - do not modify
          /// the contents of this method with the code editor.
          /// </summary>
          private void InitializeComponent()
          {
             this.textBox2 = new System.Windows.Forms.TextBox();
             this.textBox1 = new System.Windows.Forms.TextBox();
             this.button1 = new System.Windows.Forms.Button();
             this.button2 = new System.Windows.Forms.Button();
             this.SuspendLayout();
             // 
             // textBox2
             // 
             this.textBox2.BackColor = System.Drawing.SystemColors.Control;
             this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.None;
             this.textBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
             this.textBox2.ForeColor = System.Drawing.SystemColors.WindowText;
             this.textBox2.Location = new System.Drawing.Point(264, 56);
             this.textBox2.Multiline = true;
             this.textBox2.Name = "textBox2";
             this.textBox2.Size = new System.Drawing.Size(240, 232);
             this.textBox2.TabIndex = 2;
             this.textBox2.Text = "";
             // 
             // textBox1
             // 
             this.textBox1.Location = new System.Drawing.Point(16, 48);
             this.textBox1.Multiline = true;
             this.textBox1.Name = "textBox1";
             this.textBox1.Size = new System.Drawing.Size(240, 240);
             this.textBox1.TabIndex = 0;
             this.textBox1.Text = "textBox1";
             // 
             // button1
             // 
             this.button1.Location = new System.Drawing.Point(352, 296);
             this.button1.Name = "button1";
             this.button1.TabIndex = 1;
             this.button1.Text = "Build";
             this.button1.Click += new System.EventHandler(this.button1_Click);
             // 
             // button2
             // 
             this.button2.Location = new System.Drawing.Point(432, 296);
             this.button2.Name = "button2";
             this.button2.TabIndex = 1;
             this.button2.Text = "Run";
             this.button2.Click += new System.EventHandler(this.button1_Click);
             // 
             // Form1
             // 
             this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
             this.ClientSize = new System.Drawing.Size(512, 325);
             this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                            this.button2,
                                                            this.textBox2,
                                                            this.button1,
                                                            this.textBox1});
             this.Name = "Form1";
             this.Text = "Form1";
             this.ResumeLayout(false);
    
          }
          #endregion
    
          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          [STAThread]
          static void Main() 
          {
             Application.Run(new Form1());
          }
    
          private void button1_Click(object sender, System.EventArgs e)
          {
             CSharpCodeProvider codeProvider = new CSharpCodeProvider();
             ICodeCompiler icc = codeProvider.CreateCompiler();
             string Output = "Out.exe";
             Button ButtonObject = (Button) sender;
    
             textBox2.Text = "";
             System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
             //Make sure we generate an EXE, not a DLL
             parameters.GenerateExecutable = true;
             parameters.OutputAssembly = Output;
             CompilerResults results = icc.CompileAssemblyFromSource(parameters,textBox1.Text);
    
             if (results.Errors.Count > 0)
             {
                textBox2.ForeColor = Color.Red;
                foreach(CompilerError CompErr in results.Errors)
                {
                   textBox2.Text = textBox2.Text +
                               "Line number " + CompErr.Line + 
                               ", Error Number: " + CompErr.ErrorNumber + 
                               ", '" + CompErr.ErrorText + ";" + 
                               Environment.NewLine + Environment.NewLine;
                }
             }
             else
             {
                //Successful Compile
                textBox2.ForeColor = Color.Blue;
                textBox2.Text = "Success!";
                //If we clicked run then launch our EXE
                if (ButtonObject.Text == "Run") Process.Start(Output);
                
             }
    
          }
       }
    }
    					
  3. Run the project. After Form1 loads, click the Build button. Notice that you get a compiler error.
  4. Next, copy the following text into the textbox, replacing any existing text:
    using System;
    
    namespace HelloWorld
    {
    	/// <summary>
    	/// Summary description for Class1.
    	/// </summary>
    	class HelloWorldClass
    	{
    		static void Main(string[] args)
    		{
    			Console.WriteLine("Hello World!");
    			Console.ReadLine();
    		}
    	}
    }
    					
  5. Click Build again. The compile should be successful.
  6. Click Run, and it will compile the code and run the resulting executable file. The compile creates a executable file called "Out.exe", which is saved in the same folder as the application that you are running.

    NOTE: You can modify the code in the textbox to see different compiler errors. For example, delete one of the semi-colons and rebuild the code.
  7. Lastly, modify the code in the textbox to output another line of text to the console window. Click Run to see the output.

Modification Type:MinorLast Reviewed:8/30/2004
Keywords:kbBCL kbCompiler kbhowto kbProd2Web KB304655 kbAudDeveloper