Compile and Run Dynamic Code, Without Generating Exe

Compile and run dynamic code, without generating EXE?

using (Microsoft.CSharp.CSharpCodeProvider foo = 
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
"public class FooClass { public string Execute() { return \"output!\";}}"
);

var type = res.CompiledAssembly.GetType("FooClass");

var obj = Activator.CreateInstance(type);

var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
}

This compiles a simple class from the source code string included, then instantiates the class and reflectively invokes a function on it.

Is it possible to dynamically compile and execute C# code fragments?

The best solution in C#/all static .NET languages is to use the CodeDOM for such things. (As a note, its other main purpose is for dynamically constructing bits of code, or even whole classes.)

Here's a nice short example take from LukeH's blog, which uses some LINQ too just for fun.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

class Program
{
static void Main(string[] args)
{
var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
parameters.GenerateExecutable = true;
CompilerResults results = csc.CompileAssemblyFromSource(parameters,
@"using System.Linq;
class Program {
public static void Main(string[] args) {
var q = from i in Enumerable.Range(1,100)
where i % 2 == 0
select i;
}
}");
results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
}
}

The class of primary importance here is the CSharpCodeProvider which utilises the compiler to compile code on the fly. If you want to then run the code, you just need to use a bit of reflection to dynamically load the assembly and execute it.

Here is another example in C# that (although slightly less concise) additionally shows you precisely how to run the runtime-compiled code using the System.Reflection namespace.

Dynamically create a compiled .NET exe from source code?

Take a look at CSharpCodeProvider, which can essentially be used take a string containing source code and compile it to an assembly (EXE or DLL), or if you require, an in memory assembly.

You can also use the codeDOM for the code generation side of things. Take a look at 'Generating Source Code and Compiling a Program from a CodeDOM Graph' as a starting point.

Compiling code dynamically using C#

Two possibilities:

  1. Reflection.Emit
  2. System.CodeDom.Compiler

UPDATE:

As request in the comments section here's a full example illustrating the usage of Reflection.Emit to dynamically build a class and add a static method to it:

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;

public class NotDynamicClass
{
private readonly List<string> values = new List<string>();

public void AddValue(string value)
{
values.Add(value);
}

public void ProcessValues()
{
foreach (var item in values)
{
Console.WriteLine(item);
}
}
}

class Program
{
public static void Main()
{
var assemblyName = new AssemblyName("DynamicAssemblyDemo");
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, false);
var typeBuilder = moduleBuilder.DefineType("DynamicClass", TypeAttributes.Public);

var methodBuilder = typeBuilder.DefineMethod(
"Main",
MethodAttributes.Public | MethodAttributes.Static,
null,
new Type[0]
);

var il = methodBuilder.GetILGenerator();
var ctor = typeof(NotDynamicClass).GetConstructor(new Type[0]);
var addValueMi = typeof(NotDynamicClass).GetMethod("AddValue");
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Stloc_0);
il.DeclareLocal(typeof(NotDynamicClass));
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldstr, "One");
il.Emit(OpCodes.Callvirt, addValueMi);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldstr, "Two");
il.Emit(OpCodes.Callvirt, addValueMi);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Callvirt, typeof(NotDynamicClass).GetMethod("ProcessValues"));
il.Emit(OpCodes.Ret);
var t = typeBuilder.CreateType();
var mi = t.GetMethod("Main");
mi.Invoke(null, new object[0]);
}
}

You could put breakpoints inside your not NotDynamicClass methods and see how they get invoked.


UPDATE 2:

Here's an example with CodeDom compiler:

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.CSharp;

public class NotDynamicClass
{
private readonly List<string> values = new List<string>();

public void AddValue(string value)
{
values.Add(value);
}

public void ProcessValues()
{
foreach (var item in values)
{
Console.WriteLine(item);
}
}
}

class Program
{
public static void Main()
{
var provider = CSharpCodeProvider.CreateProvider("c#");
var options = new CompilerParameters();
var assemblyContainingNotDynamicClass = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
options.ReferencedAssemblies.Add(assemblyContainingNotDynamicClass);
var results = provider.CompileAssemblyFromSource(options, new[]
{
@"public class DynamicClass
{
public static void Main()
{
NotDynamicClass @class = new NotDynamicClass();
@class.AddValue(""One"");
@class.AddValue(""Two"");
@class.ProcessValues();
}
}"
});
if (results.Errors.Count > 0)
{
foreach (var error in results.Errors)
{
Console.WriteLine(error);
}
}
else
{
var t = results.CompiledAssembly.GetType("DynamicClass");
t.GetMethod("Main").Invoke(null, null);
}
}
}

Run dynamically compiled C# code at native speed... how?

Yes, if you invoke via a MethodInfo or a non-specific Delegate, then it will indeed be slow. The trick is: don't do that. Various approaches:

  • for individual methods, go via a basic but typed delegate, such as Action, or as a generic catch-all, Func<object[], object> - and use Delegate.CreateDelegate to create a typed delegate:

    Action doSomething = (Action)Delegate.CreateDelegate(typeof(Action), method);

    another variant of this is to use the Expression API (which has a .Compile() method), or DynamicMethod (which has CreateDelegate()). The key thing: you must get a typed delegate and invoke using typed invoke (not .DynamicInvoke).

  • for more complex cases where you are generating whole types, consider implementing an interface you know about, i.e.

    IFoo foo = (IFoo)Activator.CreateInstance(...);

    again; after the initial cast (which is very cheap) you can just use static code:

    foo.Bar();

Do not use someDelegate.DynamicInvoke(...) or someMethod.Invoke(...) if you are after any kind of performance.

Write and compile sourcecode at runtime?

Yes. It is possible. To create and compile classes, you can use CodeDOM. Then you could create instances use them in your code.

Why are you trying to do this? If you can provide more information, someone can provide better alternative.

Is it possible to create/execute code in run-time in C#?

Absolutely - that's exactly what I do for Snippy for example, for C# in Depth. You can download the source code here - it uses CSharpCodeProvider.

There's also the possibility of building expression trees and then compiling them into delegates, using DynamicMethod, or the DLR in .NET 4... all kinds of things.

Make an executable at runtime

Building an executable from scratch is hard. First, you'd need to generate machine code for what the program would do, and then you need to encapsulate such code in an executable file. That's overkill unless you want to write a compiler for a language.

These utilities that generate a self-extracting executable don't really make the executable from scratch. They have the executable pre-generated, and the data file is just appended to the end of it. Since the Windows executable format allows you to put data at the end of the file, caring only for the "real executable" part (the exe header tells how big it is - the rest is ignored).

For instance, try to generate two self-extracting zip, and do a binary diff on them. You'll see their first X KBytes are exactly the same, what changes is the rest, which is not an executable at all, it's just data. When the file is executed, it looks what is found at the end of the file (the data) and unzips it.

Take a look at the wikipedia entry, go to the external links section to dig deeper:
http://en.wikipedia.org/wiki/Portable_Executable

I only mentioned Windows here but the same principles apply to Linux. But don't expect to have cross-platform results, you'll have to re-implement it to each platform. I couldn't imagine something that's more platform-dependent than the executable file. Even if you use C# you'll have to generate the native stub, which is different if you're running on Windows (under .net) or Linux (under Mono).



Related Topics



Leave a reply



Submit