visual studio proyecto instalador hacer form exportar ejecutable crear como c# runtime-compilation

c# - instalador - exportar proyecto visual studio 2017



¿Compilar y ejecutar código dinámico, sin generar EXE? (8)

Me preguntaba si era posible compilar y ejecutar código almacenado, sin generar un archivo ejecutable o cualquier otro tipo de archivos, básicamente ejecutar el archivo desde la memoria.

Básicamente, la aplicación Principal tendrá un código almacenado (código que posiblemente se modificará), y necesitará compilar el código y ejecutarlo. sin crear ningún archivo.

crear los archivos, ejecutar el programa y luego eliminar los archivos no es una opción. El código compilado deberá ejecutarse desde la memoria.

Ejemplos de código, o punteros, o casi cualquier cosa es bienvenida :)


Aquí hay un ejemplo de cómo usar System.Linq.Expressions para agregar a la respuesta de Tim. Obviamente, no es el código más bonito, pero tenerlo en esta bonita forma de árbol hace que el desarrollo sea tan fácil.

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


En Mono usas CSharp.Evaluator. Funciona de verdad en la memoria v. Algunas de las otras soluciones mencionadas que escriben y leen en un archivo debajo del capó.


Es posible. Es fácil o difícil, dependiendo de cuánto y qué tipo de código quieres escribir.

Edición: Tenga en cuenta que, antes de .NET 4.0, System.Linq.Expressions se limita a lo que puede encajar en una sola línea de C #: es decir, no if, while, asignación de variables, etc.


Mira en System.CodeDom . Hará exactamente lo que estás buscando.


Sí, usted puede hacer esto. Es muy lento, pero ciertamente puedes hacerlo. Mire el CodeDOM o el (new CSharpCodeProvider().CreateCompiler()) en .Net.


También eche un vistazo a la incorporación de un lenguaje de secuencias de comandos como Python, Ruby, Lua, etc. Todos ellos admiten la ejecución de código desde la memoria sin que se escriba nada en el disco.


Es difícil, si no imposible, compilar y ejecutar C # sin crear un archivo, porque ... Bueno, eso es lo que compila: convertir un idioma en un archivo ejecutable. Lo que estás buscando es algún tipo de funcionalidad de scripting. Lo que describió en su pregunta es esencialmente la diferencia entre un lenguaje interpretado y un lenguaje compilado . Ver Wikipedia: Lenguaje de scripting .

Dependiendo de para qué utilizará esta función, podría hacer un gran uso de un lenguaje de scripting como Python, Ruby o Lua. Aquí hay un ejemplo: ¿Cómo ejecuto un script de Python desde C #?

Esto haría que su aplicación dependiera de python.exe (o cualquier ejecutable que necesitaría para ejecutar el lenguaje de scripting que elija). Si desea evitar eso, puede que no sea demasiado difícil crear su propio lenguaje de secuencias de comandos para el que se ejecuta su aplicación en función de lo que necesite hacer con su secuencia de comandos inyectada.

Edit: Ese primer párrafo es basura. Lo siento. Consulte http://msdn.microsoft.com/en-us/library/8ffc3x75%28v=vs.110%29.aspx


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

Esto compila una clase simple de la cadena de código fuente incluida, luego crea una instancia de la clase e invoca de manera reflexiva una función en ella.