3

我目前在一家从事微加工/精细机械的研究机构工作,并被要求为我们在一个实验室中使用的当前设置开发控制器软件。

我们有一个纳米级和一些其他设备,如快门和滤光轮,应该通过中央应用程序进行控制。该软件提供了用于执行的预配置作业,这些作业基本上是为舞台生成命令的算法,并用于使用激光将不同的图案写入样本(例如矩形、圆柱体等)

现在,如果提供某种可能性来在运行时扩展此预定义作业列表,那就太好了,这意味着用户可以添加所提供的算法。

我是 C# 新手(通常是桌面应用程序新手),所以如果您能给我一些关于如何完成此操作或我应该从哪里开始寻找的提示,我将非常感激。

4

1 回答 1

2

我使用 .NET 集成的 C# 编译器完成了这个“脚本”操作。
这是一些工作要做,但基本上看起来像这样:

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

真正的代码可以做更多的事情,包括代码编辑器。
它多年来在我们的工厂运行良好。

这样,用户使用 C# 编写脚本,因此可以使用与您相同的 API。

您可以使用看起来像普通.cs文件的代码模板。它在运行时构建并提供sourceCompile.

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) { /* ... */ }
    }
}

例子:

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");
于 2013-07-18T12:45:37.970 回答