Как сохранить дерево выражений в качестве основной точки входа в новый исполняемый файл на диске?
Я пытаюсь экспортировать дерево выражений в PE-сборку в качестве основной точки входа. Я получил лямбда-выражение посредством построения дерева выражений, например:
using System.Linq;
using System;
// 1. use expression trees to create a block expression (not shown)
// 2. create a lambda expression:
LambdaExpression exprLambda = Expression.Lambda(exprBlock, new ParameterExpression[0]);
MethodBuilder mbuilder = null;
// 3. ??? Somehow get a method builder instance that works ???
// 4. Compile the lambda using the MethodBuilder instance.
exprLambda.CompileToMethod(mbuilder);
// 5. ??? Somehow get an AssemblyBuilder instance to .Save(..) this to disk. ???
Шаги 3 и 5 - это то, чего мне не хватает.
1 ответ
Решение
Вместо того, чтобы просто использовать Expression.Compile
использовать Expression.CompileToMethod(MethodBuilder)
,
Короткий, но полный пример, который создает исполняемый файл на диске с деревом выражений в качестве кода, выполняемого в точке входа:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Linq.Expressions;
class Program
{
static void Main()
{
var asmName = new AssemblyName("Foo");
var asmBuilder = AssemblyBuilder.DefineDynamicAssembly
(asmName, AssemblyBuilderAccess.RunAndSave);
var moduleBuilder = asmBuilder.DefineDynamicModule("Foo", "Foo.exe");
var typeBuilder = moduleBuilder.DefineType("Program", TypeAttributes.Public);
var methodBuilder = typeBuilder.DefineMethod("Main",
MethodAttributes.Static, typeof(void), new[] { typeof(string) });
Expression<Action> action = () => Console.WriteLine("Executed!");
action.CompileToMethod(methodBuilder);
typeBuilder.CreateType();
asmBuilder.SetEntryPoint(methodBuilder);
asmBuilder.Save("Foo.exe");
}
}