2013-07-18 26 views
3

我目前在研究機構中進行微調/精細機械,並被要求爲我們在其中一個實驗室中使用的當前設置開發控制器軟件。編寫高度用戶可擴展的C#應用​​程序的最佳實踐

我們有一個納米級和一些其他設備,如百葉窗和濾光輪,應該用中央應用程序控制。該軟件提供預先配置的執行作業,基本上是生成舞臺命令的算法,用於將激光寫入樣本中的不同圖案(例如矩形,圓柱等)。

現在它會能夠提供某種可能性來擴展運行時預定義作業的列表,這意味着像用戶提供的那些算法可以被添加。

我是一個C#新手(和一般的桌面應用程序新手),所以我非常感謝你,如果你能給我一些關於如何完成這個任務或者我應該開始尋找的提示。

+3

你嘗試過這麼遠嗎?你可以看看託管擴展性框架(http://msdn.microsoft.com/en-us/library/dd460648.aspx) –

+0

其實我偶然發現了MEF,同時使用谷歌搜索,但是到目前爲止我沒有做任何事情這個方向,因爲我仍然在研究應用程序的更基本的東西,並認爲在開始之前向專業人士提供正確方向的提示可能是一個好主意 - 所以非常感謝,我一定會進入這個! – user871784

回答

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文件的代碼模板。它在運行時生成並提供給Compilesource參數。

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"); 
+0

這就是我希望能夠做到的,非常感謝!你是否碰巧有這個可以提供的工作演示? – user871784

+0

對不起,但整個代碼都是由我們公司所有。我會試着提供一個這樣的例子,等待我的編輯。 – joe

+0

非常感謝你 - 這真棒!!!!! – user871784