4

I am currently at a research institute that does micromaching/fine mechanics and was asked to develop a controller software for the current setup we use in one of our labs.

We have a nano stage and some other equipment like shutters and filter wheels that should be controlled with a central application. The software provides pre-configured jobs for execution, which are basically algorithms that generate commands for the stage and are used to write different patterns with a laser into the samples (for example rectangles, cylinders, etc.)

Now it would be great to provide some kind of possibility to extend this list of predefined jobs on runtime, which means that algorithms like the ones provided can be added by the user.

I'm a C# newbie (and a Desktop application newbie in general) so I am extremely thankful if you can give me some hints on how this could be done or where I should start looking.

oleksii
  • 35,458
  • 16
  • 93
  • 163
user871784
  • 1,247
  • 4
  • 13
  • 32
  • 4
    What have you tried so far? You could take a look at the Managed Extensibility Framework (http://msdn.microsoft.com/en-us/library/dd460648.aspx) – Neil Mountford Jul 18 '13 at 12:39
  • actually i stumbled over MEF while googling, i however didn't do anything so far in this direction as i'm still working on the more basic stuff of the app and thought it might be a good idea to ask the pros for some hints in the right direction before starting - so thanks a lot, i'll definitely get into this! – user871784 Jul 18 '13 at 13:19

1 Answers1

3

I did this 'script' thing using the .NET integrated C# compiler.
It is some work to do but basically is looks like this:

    public Assembly Compile(string[] source, string[] references) {
        CodeDomProvider provider = new CSharpCodeProvider();
        CompilerParameters cp = new CompilerParameters(references);
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
        cp.TreatWarningsAsErrors = false;

        try {
            CompilerResults res = provider.CompileAssemblyFromSource(cp, source);
            // ...
            return res.Errors.Count == 0 ? res.CompiledAssembly : null;
        }
        catch (Exception ex) {
            // ...
            return null;
        }
    }

    public object Execute(Assembly a, string className, string methodName) {
        Type t = a.GetType(className);
        if (t == null) throw new Exception("Type not found!");
        MethodInfo method = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);          // Get method
        if (method == null) throw new Exception("Method '" + methodName + "' not found!");                                  // Method not found

        object instance =  Activator.CreateInstance(t, this);
        object ret = method.Invoke(instance, null); 
        return ret;
    }

The real code does a lot more things, including a code editor.
It works very well for years now in our factory.

This way the users use C# for the scripts and can therefore use the same API as you do.

You can use a code template that looks like a plain .cs file. It is build at runtime and provided to the source parameter of Compile.

using System;
using System.IO;
using ...

namespace MyCompany.Stuff {
    public class ScriptClass {
        public object main() {

            // copy user code here
            // call your own methods here

        }

        // or copy user code here

        private int test(int x) { /* ... */ }
    }
}

Example:

string[] source = ??? // some code from TextBoxes, files or whatever, build with template file...
string[] references = new string[] { "A.dll", "B.dll" };

Assembly a = Compile(source, references);
object result = Execute(a, "MyCompany.Stuff.ScriptClass", "main");
joe
  • 8,344
  • 9
  • 54
  • 80
  • That's pretty much what i was hoping to be able to do, thanks alot! Do you happen to have a working demo of this that you can provide? – user871784 Jul 18 '13 at 13:21
  • I'm sorry, but the entire code is owned by our company. I will try to provide a example of this, just wait for my edit. – joe Jul 18 '13 at 13:35