it-swarm.com.de

Was ist die beste Skriptsprache, die in eine C # -desktopanwendung eingebettet werden kann?

Wir schreiben eine komplexe, umfassende Desktop-Anwendung und müssen Flexibilität in den Berichtsformaten bieten, sodass wir dachten, wir würden unser Objektmodell nur einer Skriptsprache aussetzen. Es war Zeit, als dies VBA bedeutete (was immer noch eine Option ist), aber das verwaltete Code-Derivat VSTA (glaube ich) scheint an der Rebe verwelkt zu sein.

Was ist jetzt die beste Wahl für eine eingebettete Skriptsprache unter Windows .NET?

94
Ewan Makepeace

Ich habe CSScript mit erstaunlichen Ergebnissen verwendet. Das reduziert wirklich die Notwendigkeit, in meinen skriptfähigen Apps Bindungen und andere einfache Dinge zu erledigen. 

21
Hector Sosa Jr

Ich persönlich würde C # als Skriptsprache verwenden. Das .NET-Framework (und Mono, dank Matthew Scharley) enthält die Compiler für jede .NET-Sprache im Framework selbst.

Grundsätzlich besteht die Implementierung dieses Systems aus zwei Teilen.

  1. Erlauben Sie dem Benutzer, den Code zu kompilieren Dies ist relativ einfach und kann in nur wenigen Codezeilen ausgeführt werden (obwohl Sie möglicherweise einen Fehlerdialog hinzufügen möchten, der je nach Dutzend weiterer Codezeilen mehr wäre.) auf wie nutzbar Sie es wollen).

  2. Erstellen und verwenden Sie Klassen, die in der kompilierten Assembly enthalten sind. Dies ist etwas schwieriger als im vorherigen Schritt (erfordert ein wenig Nachdenken). Grundsätzlich sollten Sie die kompilierte Assembly lediglich als "Plug-In" für das Programm behandeln. Es gibt eine Reihe von Tutorials, in denen Sie ein Plug-in-System in C # erstellen können (Google ist Ihr Freund).

Ich habe eine "schnelle" Anwendung implementiert, um zu zeigen, wie Sie dieses System implementieren können (einschließlich 2 Arbeitsskripten!). Dies ist der vollständige Code für die Anwendung. Erstellen Sie einfach einen neuen und fügen Sie den Code in die Datei "program.cs" .. ein. An dieser Stelle muss ich mich für den großen Teil des Codes entschuldigen, den ich gerade einfügen möchte (ich Ich wollte nicht, dass es so groß ist, aber ich habe mich mit meinem Kommentar ein wenig mitreißen lassen.)


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
                        }
                    }
                }
            }
        }
    }
}
107
Grant Peters

IronPython . Hier ist eine Übersicht über wie man es einbindet .

36
Ben Hoffstein

Die PowerShell-Engine wurde so konzipiert, dass sie problemlos in eine Anwendung eingebettet werden kann, um sie skriptfähig zu machen. Tatsächlich ist die PowerShell-CLI nur eine textbasierte Schnittstelle für die Engine.

Bearbeiten: Siehe http://blogs.msdn.com/powershell/archive/2007/08/29/making-applications-scriptable-via-powershell.aspx

19
Rodrick Chapman

Boo Sprache.

13
jop

Meine bevorzugte Scriptsprache wäre in diesen Tagen Lua . Es ist klein, schnell, sauber, vollständig dokumentiert, gut unterstützt, hat eine großartige Community , die von vielen großen Unternehmen der Branche genutzt wird (Adobe, Blizzard, EA Games), auf jeden Fall einen Versuch wert.

Für die Verwendung mit .NET-Sprachen bietet das LuaInterface -Projekt alles, was Sie brauchen. 

8
Remo.D

Warum probieren Sie nicht C #? Mono hat ein großartiges neues Projekt speziell für die dynamische Auswertung von C #:

http://tirania.org/blog/archive/2008/Sep-10.html

3
DAC

IronRuby wie oben erwähnt. Ein interessantes Projekt für mich als C # -Programmierer ist C # Eval Support in Mono . Es ist jedoch noch nicht verfügbar (wird Teil von Mono 2.2 sein).

2
Borek Bernard

Eine weitere Abstimmung für IronPython. Das Einbetten ist einfach, die Zusammenarbeit mit .Net-Klassen ist unkompliziert, und Python.

2
Robert Rossney

Versuchen Sie es mit Ela . Dies ist eine funktionale Sprache, die Haskell ähnelt und in jede .Net-Anwendung embedded eingebettet werden kann. Auch hat es eine einfache, aber brauchbare IDE.

Ich kann vorschlagen, S # was ich derzeit pflege. Es ist ein Open Source-Projekt, das in C # geschrieben und für .NET-Anwendungen entwickelt wurde.

Ursprünglich (2007-2009) wurde es unter http://www.codeplex.com/scriptdotnet gehostet, aber kürzlich wurde es zu github verschoben.

1
Peter

JScript.NET ist gut. Fiddler benutzt es.

1
Mark Cidade

Ich habe gerade ein Plugin für einen Client erstellt, das es ihnen ermöglicht, C # -Code in Modulen zu schreiben, die sich wie VBA für Office verhalten. 

0
Mark

Ich habe Lua vor verwendet; in einer Delphi-App, aber es kann in viele Dinge eingebettet werden. Es wird in Photoshop Lightroom von Adobe verwendet.

0
Tony

Ich mag Scripting mit C # selbst. Jetzt, im Jahr 2013, gibt es eine recht gute Unterstützung für C # -Skripting. Immer mehr Bibliotheken dafür stehen zur Verfügung.

Script C # code unterstützt Mono sehr gut. Sie können es mit .NET verwenden, indem Sie einfach Mono.CSharp.dll in Ihre Anwendung aufnehmen. Für eine C # -Skriptanwendung, die ich ausgecheckt habe CShell

Schauen Sie sich auch die `ScriptEngine 'in Roslyn an, die von Microsoft stammt, aber dies ist nur CTP.

Wie bereits erwähnt wurde, gibt es CS-Script auch schon eine ganze Weile.

0
lukebuehler

Ich habe das noch nicht ausprobiert, sieht aber ziemlich cool aus:

http://www.codeplex.com/scriptdotnet

0
mattlant