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.
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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With