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

Compiling and Executing Code at Runtime

Rate me:
Please Sign up or sign in to vote.
4.48/5 (27 votes)
10 Dec 20043 min read 118.7K   3.2K   58   15
This article describes how easy it is to run uncompiled code at runtime.

Introduction

Well, this is my first article at The Code Project, so I'll try my best to stay on topic. I was recently interested in creating a sort of precedence calculator library. I was about 10% underway when I suddenly had a thought. What if instead I could just use C# code, compile and execute it, then get the result of the mathematical equation back.

Well, I figured it wouldn't be easy, but there must be a way of making it work. Turns out I was wrong, it was easy. But, I wanted it to be even easier. I wanted to abstract this concept enough that all I would have to do is pass in the code (or for a more complex situation, the code and some parameters describing what to run).

C#
private Assembly BuildAssembly(string code)
{
    Microsoft.CSharp.CSharpCodeProvider provider = 
       new CSharpCodeProvider();
    ICodeCompiler compiler = provider.CreateCompiler();
    CompilerParameters compilerparams = new CompilerParameters();
    compilerparams.GenerateExecutable = false;
    compilerparams.GenerateInMemory = true;
    CompilerResults results = 
       compiler.CompileAssemblyFromSource(compilerparams, code);
    if (results.Errors.HasErrors)
    {
        StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
        foreach (CompilerError error in results.Errors )
        {
            errors.AppendFormat("Line {0},{1}\t: {2}\n", 
                   error.Line, error.Column, error.ErrorText);
        }
        throw new Exception(errors.ToString());
    }
    else
    {
        return results.CompiledAssembly;
    }
}

This is the core of my library. This function builds the Assembly object and stores it in memory. As you can see, I'm using the C# code provider. To compile VB.NET code (or any other code for that matter) is as simple as changing the provider class. I told the compiler to generate a DLL by setting the GenerateExecutable to false, then told it to keep the DLL in memory instead of creating a file on the local disk. Any errors will be caught and displayed much like they are in Visual Studio .NET. Finally, if the compilation is successful, the Assembly object is returned.

C#
public object ExecuteCode(string code, 
    string namespacename, string classname,
    string functionname, bool isstatic, params object[] args)
{
    object returnval = null;
    Assembly asm = BuildAssembly(code);
    object instance = null;
    Type type = null;
    if (isstatic)
    {
        type = asm.GetType(namespacename + "." + classname);
    }
    else
    {
        instance = asm.CreateInstance(namespacename + "." + classname);
        type = instance.GetType();
    }
    MethodInfo method = type.GetMethod(functionname);
    returnval = method.Invoke(instance, args);
    return returnval;
}

This is the pubic interface to my library. Very straight forward, pass in the code (which could even be read from a C# file on your disk), pass in the namespace that contains the executing class, pass in the class of the executing function, pass in the function to be executed, specify if the executing function is static or not, and finally the params array for any parameters that the executing function calls for. With this setup, you could theoretically execute code that uses multiple namespaces. As long as the code is good and you specify the correct parameters, it can be done.

One thing that cannot be done with this library (at the moment at least) is running code that calls for referenced namespaces to external DLLs. This is possible, it is part of the compiler parameters, I just haven't set it up yet.

That's basically it, that's all the code you need to compile and execute uncompiled code at runtime. Pretty nifty stuff, the practical applications for this are numerous. Personally, I'm going to continue with my calculator project for now, but feel free to use this library or do whatever.

The library also includes a template setup for doing mathematical calculations.

I also included a small test application with the library. It's nothing special, just what I used to debug this library. The instructions are pretty straight forward, the only confusing command is the Execute command '/x' -- it takes a number of parameters and uses the following syntax:

/x myNamespace MyClass MyFunction False param1,param2,param3,etc

The False states that MyFunction is not static.

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
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionFunny Spelling Mistake Pin
Daniel Casserly1-Oct-12 1:30
Daniel Casserly1-Oct-12 1:30 
QuestionHi Pretty new at c# but what exactly do i have to give to the params object[] args at the ExecuteCode function Pin
Member 90760165-Jun-12 4:26
Member 90760165-Jun-12 4:26 
AnswerRe: Hi Pretty new at c# but what exactly do i have to give to the params object[] args at the ExecuteCode function Pin
otykier23-Aug-12 4:04
otykier23-Aug-12 4:04 
GeneralHi, there was a problem of memory. Pin
manhtantau31-Mar-11 17:57
manhtantau31-Mar-11 17:57 
Hi, there was a problem of memory. Because when we use this solution, the memory will increase by the new assembly we create.
GeneralRe: Hi, there was a problem of memory. Pin
Member 139774067-Feb-20 9:14
Member 139774067-Feb-20 9:14 
Generalicon Pin
vishal108223-Aug-09 2:44
vishal108223-Aug-09 2:44 
GeneralSome minor facility Pin
Gucman5-Jun-06 1:14
Gucman5-Jun-06 1:14 
QuestionPerformance? Pin
Daniel Hilgarth4-May-06 2:36
Daniel Hilgarth4-May-06 2:36 
GeneralWonderful Example - some simplification Pin
jeff_bramlett@hotmail.com27-Mar-06 3:46
jeff_bramlett@hotmail.com27-Mar-06 3:46 
GeneralNull Reference Special Note Pin
luniv040425-Aug-05 2:53
luniv040425-Aug-05 2:53 
GeneralJust the thing I was looking for. Pin
wurlii22-Feb-05 5:47
wurlii22-Feb-05 5:47 
GeneralGreat Article! Pin
Tomas Deml30-Dec-04 22:46
Tomas Deml30-Dec-04 22:46 
GeneralThought You Might Be Interested... Pin
Eric Astor12-Dec-04 15:06
Eric Astor12-Dec-04 15:06 
Generalexisting C# open source programmable calculator Pin
zxcv123412341234123411-Dec-04 7:39
zxcv123412341234123411-Dec-04 7:39 
GeneralSource Code Download Link Pin
patsissons10-Dec-04 21:23
patsissons10-Dec-04 21:23 

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.