Click here to Skip to main content
15,860,972 members
Articles / Programming Languages / C#
Article

Compiling code during runtime

Rate me:
Please Sign up or sign in to vote.
4.71/5 (23 votes)
8 May 20053 min read 164.6K   4.3K   75   29
This article shows how to compile code during runtime.

Image 1

Introduction

In some cases it is very useful to compile the source code during execution. For this situation you can use the namespace Microsoft.CSharp. This namespace contains the class CSharpCodeProvider. Using the CSharpCodeProvider you can have access to the C#-compiler. Please note that you can use the compiler with VB.NET also, just use the namespace Microsoft.VisualBasic and the class VBCodeProvider. In Addition to be able to compile your code on the fly you have to add the System.CodeDom and the System.CodeDom.Compiler namespaces.

First step

In this example we will use a RichTextBox in which we'll load some example-code. After that you will be able to compile the code. In this step we'll have a closer look at the source code of the application:

C#
CSharpCodeProvider csp = new CSharpCodeProvider();
ICodeCompiler cc = csp.CreateCompiler();

Using CSharpCodeProvider we gain access to the compiler. Using this compiler we are able to use the csc.exe without any need for the command line. To compile the example-code successfully we have to set some compiler parameters. They include which assemblies should be referred to, where the output assembly has to be stored, which warning level we want to use and some other stuff. The compiler options that we have set are the same as the compiler options you have set using the csc.exe:

C#
CompilerParameters cp = new CompilerParameters();
cp.OutputAssembly = Application.StartupPath + "\\TestClass.dll";
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.Data.dll");
cp.ReferencedAssemblies.Add("System.Xml.dll");
cp.ReferencedAssemblies.Add("mscorlib.dll");
cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");
cp.ReferencedAssemblies.Add("CSharpScripter.exe");
            
cp.WarningLevel = 3;

cp.CompilerOptions = "/target:library /optimize";
cp.GenerateExecutable = false;
cp.GenerateInMemory = false;

The CompilerParameters class has a property GenerateInMemory. We set this to false because we want to write the assembly to disk and not to memory.

The compilation

After the compilation process we want to know the results, so we create a new instance of the class CompilerResults. CompilerResults needs the parameter tempFiles. These are the files that will be generated by the compiler during compilation. Create an instance of TempFileCollection and set the path to the location where we create the temporary files. If you want to keep the files after compilation set the second parameter of the TempFileCollection to true, otherwise false:

C#
System.CodeDom.Compiler.TempFileCollection tfc = 
                new TempFileCollection(Application.StartupPath, false);
CompilerResults cr  = new CompilerResults(tfc);

Now we can compile our example code. There are different possibilities that are given by the CodeCompiler. In our case we use the method CompileAssemblyFromSource:

C#
cr = cc.CompileAssemblyFromSource(cp, this.rtfCode.Text);
System.Collections.Specialized.StringCollection sc = cr.Output;
foreach (string s in sc) 
{
    Console.WriteLine(s);
}

After compilation we write the created output to the console. In some cases there may be some compiling errors. You can catch them looking at the property Errors of the CompilerResults object:

C#
if (cr.Errors.Count > 0) 
{
    foreach (CompilerError ce in cr.Errors) 
    {
        Console.WriteLine(ce.ErrorNumber + ": " + ce.ErrorText);
    }
    MessageBox.Show(this, "Errors occoured", "Errors", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
    this.btnExecute.Enabled = false;
} 
else 
{
    this.btnExecute.Enabled = true;
}

The execution

Now we've compiled our example code and want to execute it. As you can see within the source code of the sample application, I have created an interface called Command, which includes the method Execute(). Our example code is the implementation of this interface.

To execute the assembly we have to create a new application domain in which the assembly should be loaded. So that we are able to unload the assembly. We use ShadowCopyFiles, because of this we are able to override the original assembly:

C#
AppDomainSetup ads = new AppDomainSetup();
ads.ShadowCopyFiles = "true";
AppDomain.CurrentDomain.SetShadowCopyFiles();
AppDomain newDomain = AppDomain.CreateDomain("newDomain");

We've created the new application domain, and now we want to load the assembly by doing the following lines:

C#
byte[] rawAssembly = loadFile("TestClass.dll");
Assembly assembly = newDomain.Load(rawAssembly, null);

OK, the assembly is loaded, now we want to execute the sample code which will show us a simple MessageBox:

C#
Command testClass = 
        (Command)assembly.CreateInstance("CSharpScripter.TestClass");
testClass.Execute();

After showing the MessageBox we will unload the assembly and the application domain:

C#
testClass = null;
assembly = null;
AppDomain.Unload(newDomain);
newDomain = null;

History

  • 2005/09/05 - Initial article.
  • 2005/10/05 - Added how to catch errors.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader
Austria Austria
Norbert Eder currently works as a .NET software architect at UPPER Network. He writes books and articles about WPF, Silverlight and Windows Phone 7.

For further information see his website or his project site

Comments and Discussions

 
QuestionStill helpful after 11 years... Pin
szataniel6-Apr-16 1:07
szataniel6-Apr-16 1:07 
GeneralMy vote of 5 Pin
Mahsa Hassankashi8-Mar-15 12:35
Mahsa Hassankashi8-Mar-15 12:35 
SuggestionModify the "Load Example" Code Pin
Simone Popolizio7-Feb-15 13:34
Simone Popolizio7-Feb-15 13:34 
Questionsimilar application using asp.net web application Pin
Member 103913715-Dec-13 8:20
Member 103913715-Dec-13 8:20 
Questionc++ Pin
Ruth Aanie20-Feb-13 21:52
Ruth Aanie20-Feb-13 21:52 
GeneralMy vote of 5 Pin
version_2.013-Jun-11 22:14
version_2.013-Jun-11 22:14 
GeneralInvalid search path 'C:\\Program Files\\Microsoft Visual Studio .NET\\FrameworkSDK\\Lib\\ Pin
jadoul michel14-Feb-10 9:07
jadoul michel14-Feb-10 9:07 
QuestionHow about Creating assembly without C# file Pin
abcxyz8212-Jun-07 8:29
abcxyz8212-Jun-07 8:29 
GeneralInteracting with the script runner Pin
lshyamal31-May-07 20:48
lshyamal31-May-07 20:48 
Generalcompiling code with assemply Info (in Properties Folder) Pin
abedo19827-May-07 9:37
abedo19827-May-07 9:37 
GeneralcrResults.Errors.Count Pin
nasambur20-Feb-07 23:14
nasambur20-Feb-07 23:14 
GeneralRe: crResults.Errors.Count Pin
Norbert Eder21-Feb-07 1:19
Norbert Eder21-Feb-07 1:19 
GeneralRe: crResults.Errors.Count Pin
nasambur21-Feb-07 16:01
nasambur21-Feb-07 16:01 
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
wlbkeats7-Dec-06 23:28
wlbkeats7-Dec-06 23:28 
AnswerRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
Norbert Eder10-Dec-06 19:59
Norbert Eder10-Dec-06 19:59 
QuestionHow to debug the dynamic code ? Pin
sakumira28-Nov-06 17:05
sakumira28-Nov-06 17:05 
AnswerRe: How to debug the dynamic code ? Pin
Norbert Eder10-Dec-06 19:46
Norbert Eder10-Dec-06 19:46 
QuestionAJ Pin
almarma413-Nov-06 3:40
almarma413-Nov-06 3:40 
AnswerRe: AJ Pin
Norbert Eder10-Dec-06 19:48
Norbert Eder10-Dec-06 19:48 
GeneralRe: AJ Pin
zhudexiang9-Mar-07 2:40
zhudexiang9-Mar-07 2:40 
GeneralRe: AJ Pin
André Kurth3-Apr-07 22:03
André Kurth3-Apr-07 22:03 
GeneralRe: AJ Pin
BrianARice5-Aug-09 4:18
BrianARice5-Aug-09 4:18 
GeneralRe: AJ Pin
Eranda Ketawalage6-Nov-11 5:23
Eranda Ketawalage6-Nov-11 5:23 
QuestionRecompile code Pin
Dr Vespa18-Jan-06 5:15
Dr Vespa18-Jan-06 5:15 
AnswerRe: Recompile code Pin
Norbert Eder24-Jan-06 22:11
Norbert Eder24-Jan-06 22:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.