views:

161

answers:

6

I have a desktop application written in C# i'd like to make scriptable on C#/VB. Ideally, the user would open a side pane and write things like /// foreach (var item in myApplication.Items) item.DoSomething(); /// Having syntax highlighting + code completion would be awesome but I could live without it. I would not want to require users to have Visual Studio 2010 installed.

I am thinking about invoking the compiler, loading and running the output assembly.

Is there a better way?

Is Microsoft.CSharp the answer? (see http://channel9.msdn.com/pdc2008/TL16/)

+1  A: 

Use a scripting language. TCL, LUA or even javascript comes to mind.

Using tcl is really easy:

using System.Runtime.InteropServices;
using System;

namespace TclWrap {
    public class TclAPI {
         [DllImport("tcl84.DLL")]
         public static extern IntPtr Tcl_CreateInterp();
         [DllImport("tcl84.Dll")]
         public static extern int Tcl_Eval(IntPtr interp,string skript);
         [DllImport("tcl84.Dll")]
         public static extern IntPtr Tcl_GetObjResult(IntPtr interp);
         [DllImport("tcl84.Dll")]
         public static extern string Tcl_GetStringFromObj(IntPtr tclObj,IntPtr length);
    }
    public class TclInterpreter {
        private IntPtr interp;
        public TclInterpreter() {
            interp = TclAPI.Tcl_CreateInterp();
            if (interp == IntPtr.Zero) {
                throw new SystemException("can not initialize Tcl interpreter");
            }
        }
        public int evalScript(string script) {
            return TclAPI.Tcl_Eval(interp,script);        
        }
        public string Result {
            get { 
                IntPtr obj = TclAPI.Tcl_GetObjResult(interp);
                if (obj == IntPtr.Zero) {
                    return "";
                } else {
                    return TclAPI.Tcl_GetStringFromObj(obj,IntPtr.Zero);
                }
            }
        }
    }
}

The use it like:

TclInterpreter interp = new TclInterpreter();
string result;
if (interp.evalScript("set a 3; {exp $a + 2}")) {
    result = interp.Result;
}
Byron Whitlock
Are there any C# bridges for any of those scripting languages and if so can you provide links?
Jared Updike
+4  A: 

Have you thought about IronPython or IronRuby?

Jared Updike
Performance is something you might need to monitor. +1 for the answer though
Perpetualcoder
It depends on how much program logic is in the scriping part and how much of the heavy lifting is .NET/C# code. Python is commonly used to make large, high performance C++ programs scriptable (e.g. video games, Pixar's internal Menv animation software, etc.) but Python is not the conventional way of building new features but rather Python would allow a higher-level way of putting the existing high performance pieces together in interesting, novel ways.
Jared Updike
Or IronJS? a little more accessible to a C# dude.
Sky Sanders
@Sky Sanders: Didn't know about IronJS. Sounds really cool and I hope they can bring it into a stable release.
Jared Updike
+1  A: 

you will invoke compiler anyway, because C# is compiled language. The best way to do it can be cheched here http://msdn.microsoft.com/ru-ru/library/microsoft.csharp.csharpcodeprovider.aspx

Andrey
You will not invoke the compiler at runtime. You will invoke the clr however.
Byron Whitlock
you will invoke compiler. csc.exe will be called anyway, you can use reflector to check that
Andrey
+1  A: 

I would use powershell or MEF it really depends on what you mean be scritable and what type of application you have. The best part about powershell is its directly hostable and directly designed to use .net interfaces in a scripting manner.

rerun
A: 

What language is your application written in? If C++, you might consider Google V8, an embeddable ECMAScript/Javascript engine.

overslacked
+1  A: 

You can use the following open source solution as an example: http://coderunner.codeplex.com/

zespri