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

我想知道是否有可能编译,并运行存储的代码,而不生成一个exe或任何types的其他文件,基本上从内存中运行该文件。

基本上,主应用程序将有一些存储的代码(可能会被改变的代码),它将需要编译代码,并执行它。 而不创build任何文件。

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

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

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[] { }); } 

它从包含的源代码string编译一个简单的类,然后实例化这个类并reflection地调用一个函数。

这里是一个如何使用System.Linq.Expressions添加到Tim的答案的例子。 显然,它并不是最漂亮的代码,而是以这种漂亮的树状forms让开发变得如此简单。

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

这是可能的。 这很容易或很难,取决于你想写多less和什么样的代码。

  • 编译单行expression式: System.Linq.Expressions (简单但有限)
  • 编译整个程序: System.Reflection.Emit (很难debugging,但不是不可能的)

编辑:请注意,在.NET 4.0之前, System.Linq.Expressions仅限于您可以在一行C#中适用:也就是说,如果,而不是variables赋值等。

是的,你可以做到这一点。 这是非常缓慢的,但你当然可以做到这一点。 查看.Net中的CodeDOM或(new CSharpCodeProvider().CreateCompiler())

看看System.CodeDom 。 它会做你正在寻找的。

在单声道你使用CSharp.Evaluator。 它在内存中真正起作用v提到的其他一些解决scheme在写入文件的时候写出并回读。

还要看看embeddedPython,Ruby,Lua等脚本语言。所有这些都支持从内存中执行代码,而不会将任何内容写入磁盘。

编译和执行C#而不创build文件是很困难的,因为…编译就是把语言转换成可执行文件。 你正在寻找什么是某种脚本function。 你在你的问题中描述的实质上是解释型语言和编译型语言的区别。 参见Wikipedia:脚本语言 。

根据你将要使用的这个特性,你可以很好地使用像Python,Ruby或者Lua这样的脚本语言。 下面是一个例子: 如何从C#运行Python脚本?

这将使你的应用程序依赖于python.exe(或任何你需要运行你select的脚本语言的可执行文件)。 如果你想避免这种情况,那么根据你的注入脚本需要做什么来制作自己的脚本语言,这可能不会太难。

编辑:第一段是垃圾。 抱歉。 请参阅http://msdn.microsoft.com/en-us/library/8ffc3x75%28v=vs.110%29.aspx

Interesting Posts