稍早發表利用JScript eval()函數提供高彈性的自訂條件運算式一文,隨即獲得網友ChrisTorng迴響,提出了關於eval運算式中可能被放入大量迴圈邏輯的問題以及Build JScript.NET DLL滅少CodeDom及Reflection使用的建議。(感謝!!)

關於第一點,的確,只要在執行階段允許外界輸入程式碼執行就要承擔風險!! 即便依照MSDN的說法,eval預設只能在被限制的環境中執行,被禁止接觸檔案、網路等本機資源,已大幅減少被誤用於入侵系統的可能性。但既然開放讓別人自由寫Code,就無法杜絕別人做傻事或做壞事的可能性,這是應用此一技術時必須要有的認知。

因此我補充一下自己的實務應用情境: 核心流桯引擎會讀入一份XML設定檔決定整個作業流程,而其中部分流動走向的條件則被寫成讓eval動態運算決定的Javascript運算式(當然,其中有些預先指定的特殊符號,可以代表當時系統中某些變數的值)。如此,我們只要修改XML就可以改變或產生各式流程,不需要為了流程中的判定邏輯修改.NET程式。而此分工下,撰寫運算式的人員就是有權寫Code的開發人員,原則上我們已信任他們的專業能力與善意心態,用eval()跑運算式而不是寫在.NET元件中,純粹只是為了修改快速,開發簡便,不致因使用eval()而衍生額外的風險。也因為此一前題,才敢大膽運用此技術。

至於第二點有點意思。從VS2008起,Visual Studio IDE已不再支援編輯維護JScript.NET專案,因此要用jsc命令列工具來編譯DLL。

啟動【程式集/Microsoft Visual Studio 2008/Visual Studio Tools/Visual Studio 2008 Command Prompt】,下指令jsc /target:library source.js就可以將JScript.NET原始碼編譯成DLL。

在專案中參考這個DLL,就可像一般元件一般呼叫它囉!


Comments

# by 四成收入

我終於瞭解,你想利用 C# 和 JScript 語法有很多相同的地方,而應用 JScript .eval() 來執行 JScript / C# 的語句。對嗎? 我覺得你的第二個方法比較好。 我想你也可以在 C# 程式中直接執行 JScript,像: First: Add Reference: Microsoft.JScript Then, in the C# code, do this: try { string jsCode = @"((a+b)>0 || c>100 && (d || e))"; Microsoft.JScript.Vsa.VsaEngine vsaEngine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); string result = Microsoft.JScript.Eval.JScriptEvaluate(jsCode , "unsafe", vsaEngine ).ToString(); } catch { //... } 從來沒用過,但我知道可以用。

# by 四成收入

我終於瞭解,你想利用 C# 和 JScript 語法有很多相同的地方,而應用 JScript .eval() 來執行 JScript / C# 的語句。對嗎? 我覺得你的第二個方法比較好。 我想你也可以在 C# 程式中直接執行 JScript,像: First: Add Reference: Microsoft.JScript Then, in the C# code, do this: try { string jsCode = @"((a+b)>0 || c>100 && (d || e))"; Microsoft.JScript.Vsa.VsaEngine vsaEngine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); string result = Microsoft.JScript.Eval.JScriptEvaluate(jsCode , "unsafe", vsaEngine ).ToString(); } catch { //... } 從來沒用過,但我知道可以用。

# by 四成收入

看到報紙將有兩個颱風合力侵台 實在為台灣民眾擔心 特借此禱告台灣能安然度過颱風的肆虐 並祝中秋節愉快

# by Jeffrey

to 四成收入, 測試過可行,用Microsoft.JScript.Vsa.VsaEngine的做法看來更為簡便,感謝分享。(不過,我發現Microsoft.Vsa的東西在MSDN(http://msdn.microsoft.com/en-us/library/microsoft.vsa.aspx)裡都被註明為Obsolete過時,建議改用 ICodeCompiler,也就是前一篇說的CodeDom方法,很有趣!)

# by ChrisTorng

我昨天也有在查 Microsoft.JScript 命名空間,也看到 JScriptEvaluate(),但因「這個 API 支援 .NET Framework 基礎結構,但您不可以直接在程式碼中使用它。」,因此想說不應該來用這個... 我覺得 JScript.NET dll 應該是最好的作法,不用 Reflection,而且也不用執行時 parsing 字串 (僅有 Eval(expr) 內的 expr 才需要執行時 parsing),更不用建立編譯引擎,省下參考更複雜函式庫的需要。也不用去查完全陌生的 Microsoft.JScript 命名空間來寫完全陌生的程式碼。用接近原本 JavaScript 的語法,在一個可重覆使用的 dll 中將 JScript 的能力儘情發揮。所付出的代價僅為增加一個專案,以及修改後需要命令列編譯,應該是很划算的。 所以 CodeDomProvider.CreateProvider("JScript") 的確是用 JScript.NET 對吧?

Post a comment