Domanda

Mi chiedevo se era possibile compilare ed eseguire codice memorizzato, senza generare un file EXE o qualsiasi tipo di altri file, in pratica eseguire il file dalla memoria.

In sostanza, l'applicazione principale, avrà qualche codice memorizzato (codice che potenzialmente modificabile), e avrà bisogno di compilare il codice, ed eseguirlo. senza creare alcun file.

la creazione dei file, l'esecuzione del programma, e quindi l'eliminazione dei file non è un'opzione. il codice compilato dovrà essere eseguito a memoria.

esempi di codice, o puntatori, o praticamente qualsiasi cosa è il benvenuto:)

È stato utile?

Soluzione

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

Questa compila una semplice classe dalla stringa di codice sorgente incluso, quindi un'istanza della classe e riflessivo invoca una funzione su di esso.

Altri suggerimenti

Ecco un esempio di come utilizzare System.Linq.Expressions per aggiungere alla risposta di Tim. Ovviamente non è il codice più bello, ma averlo in questo bel albero-come forma rende lo sviluppo così facile.

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

E 'possibile. E 'facile o difficile, a seconda di quanto e che tipo di codice si vuole scrivere.

Modifica Nota che, prima di .NET 4.0, System.Linq.Expressions è limitata a ciò che si può stare su una sola riga di C #: che è, non se, mentre, assegnamento di variabile etc

Sì, si può fare questo. E 'molto lento, ma si può certamente farlo. Guardate la CodeDOM o (new CSharpCodeProvider().CreateCompiler()) in .Net.

Se vuoi in System.CodeDom. Lo farà esattamente quello che stai cercando.

In Mono si utilizza CSharp.Evaluator. Funziona veramente in memoria v. Alcune delle altre soluzioni hanno detto che scrivere e leggere di nuovo in un file sotto il cofano.

Anche dare un'occhiata a incorporare un linguaggio di scripting come Python, Ruby, Lua, ecc .. tutti coloro sostegno eseguire il codice dalla memoria senza nulla essere scritti sul disco.

E 'difficile, se non impossibile compilare ed eseguire C # senza creare un file, perché ... Beh, questo è ciò che la compilazione è- trasformare una lingua in un file eseguibile. Quello che stai cercando è un qualche tipo di funzionalità di scripting. Quello che hai descritto nella tua domanda è essenzialmente la differenza tra un interpretato lingua e un compilato la lingua. Vedere Wikipedia:. Scripting Language

A seconda di quello che verrà usato questa funzione per, si potrebbe fare grande uso di un linguaggio di scripting come Python, Ruby, o Lua. Ecco un esempio: Come faccio a eseguire uno script Python da C # ?

Questo renderebbe la vostra applicazione dipende python.exe (o qualsiasi eseguibile avresti bisogno di eseguire il linguaggio di scripting che si sceglie). Se si vuole evitare che, potrebbe non essere troppo duro per rendere il proprio linguaggio di scripting che l'applicazione fa il runtime per, a seconda di ciò che è necessario a che fare con lo script iniettato.

Modifica: Quel primo comma è spazzatura. Scusa. Vedere http://msdn.microsoft.com /en-us/library/8ffc3x75%28v=vs.110%29.aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top