编译并运行动态代码,而不生成EXE?

cae*_*say 22 c# runtime-compilation

我想知道是否可以编译,并运行存储的代码,而不生成exe或任何类型的其他文件,基本上从内存中运行该文件.

基本上,Main应用程序将有一些存储代码(可能会更改的代码),并且需要编译代码并执行它.没有创建任何文件.

创建文件,运行程序,然后删除文件不是一个选项.编译后的代码需要从内存中运行.

代码示例,或指针,或几乎任何东西都欢迎:)

Ada*_*son 36

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[] { });
}
Run Code Online (Sandbox Code Playgroud)

这将从包含的源代码字符串编译一个简单的类,然后实例化该类并反射调用它上面的函数.

  • `GenerateInMemory = true`没有顾名思义; 它会在temp目录中生成一个程序集,一旦完成就必须删除它. (5认同)
  • 好的 - 上次我这样做我必须将程序集保存在磁盘上进行调试.我可以看到`CSharpCodeProvider`编译成一个临时文件,使用`Assembly.Load(byte [])`加载该文件,然后删除它.(它无法完全绕过临时文件,因为它在下面运行_csc.exe_.) (2认同)
  • 不,这是csc.exe编译器的一个基本限制.具有讽刺意味的是,编译器是用本机C++编写的,不能与您的程序交互. (2认同)

Cha*_*ion 5

这是一个如何使用System.Linq.Expressions添加到Tim的答案的示例.显然它不是最漂亮的代码,但是以这种漂亮的树状形式使它变得如此简单.

private  Expression<IsWordChar> CreateIsWordCharExpression()
{
    var e = Expression.Parameter(typeof(int), "e");
    var c = Expression.Variable(typeof(char), "c");
    var returnLabel = Expression.Label(Expression.Label(typeof(bool)), _falseConstant);
    var lambda = Expression.Lambda<IsWordChar>(
        Expression.Block(
            new[] { c },
            Expression.IfThen(
                Expression.OrElse(
                    Expression.Equal(e, Expression.Constant(-1)),
                    Expression.Equal(e, _inputLengthVar)
                ),
                Expression.Return(returnLabel.Target, _falseConstant)
            ),
            Expression.Assign(c, Expression.MakeIndex(_str, _stringCharsPropertyInfo, new[] { e })),
            Expression.IfThenElse(
                Expression.OrElse(
                    Expression.OrElse(
                        Expression.OrElse(
                            Expression.AndAlso(
                                Expression.GreaterThanOrEqual(c, Expression.Constant('a')),
                                Expression.LessThanOrEqual(c, Expression.Constant('z'))
                            ),
                            Expression.AndAlso(
                                Expression.GreaterThanOrEqual(c, Expression.Constant('A')),
                                Expression.LessThanOrEqual(c, Expression.Constant('Z'))
                            )
                        ),
                        Expression.AndAlso(
                            Expression.GreaterThanOrEqual(c, Expression.Constant('0')),
                            Expression.LessThanOrEqual(c, Expression.Constant('1'))
                        )
                    ),
                    Expression.Equal(c, Expression.Constant('_'))
                ),
                Expression.Return(returnLabel.Target, _trueConstant),
                Expression.Return(returnLabel.Target, _falseConstant)
            ),
            returnLabel
        ),
        "IsWordChar",
        new[] { e }
    );
    return lambda;
}
Run Code Online (Sandbox Code Playgroud)