todos - ¿Cuál es el mejor lenguaje de scripting para incrustar en una aplicación de escritorio C#?
tipos de lenguaje de programacion (16)
Estamos escribiendo una aplicación de escritorio rica y compleja y necesitamos ofrecer flexibilidad en los formatos de informes, así que pensamos que simplemente expondríamos nuestro modelo de objetos a un lenguaje de scripting. El tiempo era cuando eso significaba VBA (que todavía es una opción), pero el derivado del código administrado VSTA (creo) parece haberse marchitado en la vid.
¿Cuál es ahora la mejor opción para un lenguaje de scripting incorporado en Windows .NET?
¿Por qué no probar C #? Mono tiene un gran proyecto nuevo especialmente para evaluar dinámicamente C #:
Acabo de crear un complemento para un cliente, lo que les permite escribir código C # en módulos que actúan como VBA para Office.
El motor de PowerShell fue diseñado para ser incrustado fácilmente en una aplicación para que sea susceptible de escritura. De hecho, la CLI de PowerShell es solo una interfaz basada en texto para el motor.
Editar: ver http://blogs.msdn.com/powershell/archive/2007/08/29/making-applications-scriptable-via-powershell.aspx
He usado a Lua antes; en una aplicación Delphi, pero puede integrarse en muchas cosas. Se usa en Adobe Photoshop Lightroom .
IronRuby como se mencionó anteriormente. Un proyecto interesante para mí como programador de http://tirania.org/blog/archive/2008/Sep-10.html es http://tirania.org/blog/archive/2008/Sep-10.html . Pero aún no está disponible (será parte de Mono 2.2).
JScript.NET es bueno. Fiddler lo usa.
Lenguaje Boo .
Mi lenguaje de scripting de elección sería Lua estos días. Es pequeño, rápido, limpio, totalmente documentado, bien respaldado, tiene una gran community , es utilizado por muchas grandes empresas de la industry (Adobe, Blizzard, EA Games), definitivamente vale la pena intentarlo.
Para usarlo con lenguajes .NET, el proyecto LuaInterface proporcionará todo lo que necesita.
No lo he intentado todavía, pero se ve bastante genial:
Otro voto para IronPython. Incrustarlo es simple, la interoperación con clases .Net es sencilla, y, bueno, es Python.
Personalmente, utilizaría C # como lenguaje de scripting. El framework .NET (y Mono, gracias a Matthew Scharley) en realidad incluye los compiladores para cada uno de los lenguajes .NET en el marco mismo.
Básicamente, hay 2 partes para la implementación de este sistema.
Permitir al usuario compilar el código. Esto es relativamente fácil, y se puede hacer en unas pocas líneas de código (aunque es posible que desee agregar un cuadro de diálogo de error, que probablemente sería un par de docenas más de líneas de código, dependiendo de qué tan utilizable quieres que sea).
Crear y usar clases contenidas dentro del ensamblado compilado Esto es un poco más difícil que el paso anterior (requiere un poco de reflexión). Básicamente, debería tratar el ensamblaje compilado como un "complemento" para el programa. Hay bastantes tutoriales sobre las diversas formas en que puede crear un sistema de complemento en C # (Google es su amigo).
Implementé una aplicación "rápida" para demostrar cómo puede implementar este sistema (¡incluye 2 scripts que funcionan!). Este es el código completo para la aplicación, simplemente cree uno nuevo y pegue el código en el archivo "program.cs". En este punto, debo disculparme por la gran cantidad de código que estoy a punto de pegar (no tenía la intención de que fuera tan grande, pero me dejé llevar por mis comentarios)
using System;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;
namespace ScriptingInterface
{
public interface IScriptType1
{
string RunScript(int value);
}
}
namespace ScriptingExample
{
static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
// Lets compile some code (I''m lazy, so I''ll just hardcode it all, i''m sure you can work out how to read from a file/text box instead
Assembly compiledScript = CompileCode(
"namespace SimpleScripts" +
"{" +
" public class MyScriptMul5 : ScriptingInterface.IScriptType1" +
" {" +
" public string RunScript(int value)" +
" {" +
" return this.ToString() + /" just ran! Result: /" + (value*5).ToString();" +
" }" +
" }" +
" public class MyScriptNegate : ScriptingInterface.IScriptType1" +
" {" +
" public string RunScript(int value)" +
" {" +
" return this.ToString() + /" just ran! Result: /" + (-value).ToString();" +
" }" +
" }" +
"}");
if (compiledScript != null)
{
RunScript(compiledScript);
}
}
static Assembly CompileCode(string code)
{
// Create a code provider
// This class implements the ''CodeDomProvider'' class as its base. All of the current .Net languages (at least Microsoft ones)
// come with thier own implemtation, thus you can allow the user to use the language of thier choice (though i recommend that
// you don''t allow the use of c++, which is too volatile for scripting use - memory leaks anyone?)
Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();
// Setup our options
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = false; // we want a Dll (or "Class Library" as its called in .Net)
options.GenerateInMemory = true; // Saves us from deleting the Dll when we are done with it, though you could set this to false and save start-up time by next time by not having to re-compile
// And set any others you want, there a quite a few, take some time to look through them all and decide which fit your application best!
// Add any references you want the users to be able to access, be warned that giving them access to some classes can allow
// harmful code to be written and executed. I recommend that you write your own Class library that is the only reference it allows
// thus they can only do the things you want them to.
// (though things like "System.Xml.dll" can be useful, just need to provide a way users can read a file to pass in to it)
// Just to avoid bloatin this example to much, we will just add THIS program to its references, that way we don''t need another
// project to store the interfaces that both this class and the other uses. Just remember, this will expose ALL public classes to
// the "script"
options.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
// Compile our code
CompilerResults result;
result = csProvider.CompileAssemblyFromSource(options, code);
if (result.Errors.HasErrors)
{
// TODO: report back to the user that the script has errored
return null;
}
if (result.Errors.HasWarnings)
{
// TODO: tell the user about the warnings, might want to prompt them if they want to continue
// runnning the "script"
}
return result.CompiledAssembly;
}
static void RunScript(Assembly script)
{
// Now that we have a compiled script, lets run them
foreach (Type type in script.GetExportedTypes())
{
foreach (Type iface in type.GetInterfaces())
{
if (iface == typeof(ScriptingInterface.IScriptType1))
{
// yay, we found a script interface, lets create it and run it!
// Get the constructor for the current type
// you can also specify what creation parameter types you want to pass to it,
// so you could possibly pass in data it might need, or a class that it can use to query the host application
ConstructorInfo constructor = type.GetConstructor(System.Type.EmptyTypes);
if (constructor != null && constructor.IsPublic)
{
// lets be friendly and only do things legitimitely by only using valid constructors
// we specified that we wanted a constructor that doesn''t take parameters, so don''t pass parameters
ScriptingInterface.IScriptType1 scriptObject = constructor.Invoke(null) as ScriptingInterface.IScriptType1;
if (scriptObject != null)
{
//Lets run our script and display its results
MessageBox.Show(scriptObject.RunScript(50));
}
else
{
// hmmm, for some reason it didn''t create the object
// this shouldn''t happen, as we have been doing checks all along, but we should
// inform the user something bad has happened, and possibly request them to send
// you the script so you can debug this problem
}
}
else
{
// and even more friendly and explain that there was no valid constructor
// found and thats why this script object wasn''t run
}
}
}
}
}
}
}
Puedo sugerir S# que actualmente mantengo. Es un proyecto de código abierto, escrito en C # y diseñado para aplicaciones .NET.
Inicialmente (2007-2009) se alojó en http://www.codeplex.com/scriptdotnet , pero recientemente se movió a github.
Utilicé CSScript con resultados sorprendentes. Realmente redujo el tener que hacer enlaces y otras cosas de bajo nivel en mis aplicaciones de secuencias de comandos.
IronPython . Aquí hay una descripción general de cómo insertarlo .
Me gusta escribir scripts con C # . Ahora, en 2013, existe un soporte bastante bueno para las secuencias de comandos de C #, cada vez hay más bibliotecas disponibles.
Mono tiene una gran compatibilidad con el código de script C # , y puede usarlo con .NET con solo incluir el Mono.CSharp.dll
en su aplicación. Para la aplicación de scripts C # que he creado, echa un vistazo a CShell
También consulte el `ScriptEngine ''en Roslyn que es de Microsoft, pero esto es solo CTP.
Como algunas personas ya mencionaron, CSScript ha existido por bastante tiempo también.