program story

C # 데스크톱 애플리케이션에 포함하는 데 가장 적합한 스크립팅 언어는 무엇입니까?

inputbox 2020. 8. 23. 09:07
반응형

C # 데스크톱 애플리케이션에 포함하는 데 가장 적합한 스크립팅 언어는 무엇입니까? [닫은]


우리는 복잡하고 풍부한 데스크톱 애플리케이션을 작성하고 있으며보고 형식에 유연성을 제공해야하므로 개체 모델을 스크립팅 언어에 노출시킬 것이라고 생각했습니다. 시간은 VBA (여전히 옵션 임)를 의미했지만 관리 코드 파생 VSTA (내 생각에)는 포도 나무에서 시들해진 것 같습니다.

이제 Windows .NET에서 임베디드 스크립팅 언어에 가장 적합한 선택은 무엇입니까?


놀라운 결과로 CSScript사용 했습니다 . 스크립팅 가능한 앱에서 바인딩 및 기타 낮은 수준의 작업을 수행해야하는 작업을 정말로 줄여줍니다.


개인적으로 C #을 스크립팅 언어로 사용합니다. .NET 프레임 워크 (및 Mono, Matthew Scharley 덕분에)는 실제로 프레임 워크 자체에 각 .NET 언어에 대한 컴파일러를 포함합니다.

기본적으로이 시스템의 구현에는 두 부분이 있습니다.

  1. 사용자가 코드를 컴파일하도록 허용 이것은 비교적 쉽고 몇 줄의 코드로만 수행 할 수 있습니다 (사용 방법에 따라 코드 줄이 몇 줄 더 늘어날 수있는 오류 대화 상자를 추가 할 수도 있지만 당신은 그것을 원합니다).

  2. 컴파일 된 어셈블리에 포함 된 클래스 생성 및 사용 이것은 이전 단계보다 약간 더 어렵습니다 (약간의 반영이 필요함). 기본적으로 컴파일 된 어셈블리를 프로그램의 "플러그인"으로 취급해야합니다. C #으로 플러그인 시스템을 만들 수있는 다양한 방법에 대한 튜토리얼이 꽤 많이 있습니다 (Google은 당신의 친구입니다).

이 시스템을 구현하는 방법을 보여주기 위해 "빠른"응용 프로그램을 구현했습니다 (2 개의 작업 스크립트 포함!). 이것은 응용 프로그램에 대한 완전한 코드입니다. 새 코드를 만들고 "program.cs"파일에 코드를 붙여 넣으면됩니다. 이 시점에서 나는 내가 붙여 넣을 코드의 큰 덩어리에 대해 사과해야한다. (나는 그것이 그렇게 큰 것을 의도하지 않았지만 내 주석에 약간 빠져 들었다)


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


IronPython . 삽입 방법에 대한 개요는 다음과 같습니다 .


PowerShell 엔진은 스크립트가 가능하도록 응용 프로그램에 쉽게 포함되도록 설계되었습니다. 실제로 PowerShell CLI는 엔진에 대한 텍스트 기반 인터페이스입니다.

편집 : https://devblogs.microsoft.com/powershell/making-applications-scriptable-via-powershell/ 참조


언어.


My scripting language of choice would be Lua these days. It's small, fast, clean, fully documented, well supported, has a great community , it's used by many big companies in the industry (Adobe, Blizzard, EA Games), definetely worth a try.

To use it with .NET languages the LuaInterface project will provide all you need.


Why not try C#? Mono has a great new project especially for dynamically evaluating C# :

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


IronRuby as mentioned above. An interesting project to me as a C# programmer is C# Eval support in Mono. But it's not available yet (will be part of Mono 2.2).


Another vote for IronPython. Embedding it is simple, interoperation with .Net classes is straightforward, and, well, it's Python.


I may suggest S# which I currently maintain. It is an open source project, written in C# and designed for .NET applications.

Initially (2007-2009) it was hosted at http://www.codeplex.com/scriptdotnet, but recently it was moved to github.


Try Ela. This is a functional language similar to Haskell and can be embedded into any .Net application. Even it has simple but usable IDE.


I havnt tried this yet but it looks pretty cool:

http://www.codeplex.com/scriptdotnet


I've just created a plugin for a client, allowing them to write C# code in modules that act like VBA does for Office.


I've used Lua before; in a Delphi app but it can be embedded in lots of things. It's used in Adobe's Photoshop Lightroom.


I like scripting with C# itself. Now, in 2013, there's quite good support for C# scripting, more and more libraries for it are becoming available.

Mono has a great support to script C# code, and you can use it with .NET by just including the Mono.CSharp.dll in your application. For C# scripting application that I've made check out CShell

Also check out the `ScriptEngine' in Roslyn which is from Microsoft, but this is only CTP.

As some people already mentioned, CS-Script has been around for quite a while as well.

참고URL : https://stackoverflow.com/questions/137933/what-is-the-best-scripting-language-to-embed-in-a-c-sharp-desktop-application

반응형