我想知道是否可以在不生成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[] { });
}

这将从包含的源代码字符串中编译一个简单的类,然后实例化类并反思性调用函数。

其他提示

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

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;
}

这是可能的。这很容易或很难,具体取决于您要编写的代码和哪种代码。

编辑: 请注意,在.NET 4.0之前, System.Linq.Expressions 仅限于您可以在C#的一行上适合的内容:也就是说,如果,如果,如果,如果,可变分配等。

是的,您可以做到这一点。这很慢,但是您当然可以做到。查看编码或 (new CSharpCodeProvider().CreateCompiler()) 在.net。

调查 System.CodeDom. 。它将完全按照您的需求做。

在Mono中,您使用csharp.evaluator。它确实在内存v。提到的其他一些解决方案中真正起作用,这些解决方案在引擎盖下的文件下写了并读回。

还要看一下嵌入诸如Python,Ruby,Lua等的脚本语言。所有这些支持从内存执行代码的所有支持,而没有写入磁盘上的任何内容。

如果不是不创建文件,就很难,即使不是不可能编译和执行C#,因为...嗯,这就是将语言转换为可执行文件的汇编。您正在寻找的是某种脚本功能。您在问题中描述的本质上是 解释 语言和 编译 语言。看 Wikipedia:脚本语言.

根据您将要使用此功能的内容,您可以很好地利用Python,Ruby或Lua等脚本语言。这是一个例子: 如何从C#运行Python脚本?

这将使您的应用程序取决于python.exe(或您需要运行您选择的脚本语言的任何可执行文件)。如果您想避免这种情况,根据您需要使用注入的脚本需要做什么,可以制作自己的应用程序来制作运行时的脚本语言可能并不难。

编辑:第一段是垃圾。对不起。看 http://msdn.microsoft.com/en-us/library/8ffc3x75%28v=vs.110%29.aspx

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top