C#字符串表達式計算,後臺javascript腳本計算

一直以來一直使用js引擎,也就是MSScript.ocx即Interop.MSScriptControl.dll來實現字符串表達式的計算。

但是周一在部署時發現存在64位不支持的問題,雖然開啟32位後解決瞭,但是心裡總是個疙瘩。

昨天利用C#代碼編譯功能終於解決瞭C#字符串表達式的計算的問題,方法和代碼都來自互聯網,非常感謝,也把自己修改後的分享給大傢

一、腳本方法

using System;
using System.Collections.Generic;
using System.Text;
using MSScriptControl;

namespace MyQuery.CSharpScript
{
    /// <summary>
    /// 腳本運行錯誤代理
    /// </summary>
    public delegate void RunErrorHandler();

    /// <summary>
    /// 腳本運行超時代理
    /// </summary>
    public delegate void RunTimeoutHandler();

    /// <summary>
    /// 腳本處理引擎
    /// by 開源盛世-源代碼下載網 基於網絡文章整理開發,是學習自定義腳本的產物
    /// </summary>
    public sealed class ScriptEngine
    {
        private ScriptControlClass msc;
        /// <summary>
        /// 定義腳本運行錯誤事件
        /// </summary>
        public event RunErrorHandler RunError;
        /// <summary>
        /// 定義腳本運行超時事件
        /// </summary>
        public event RunTimeoutHandler RunTimeout;

        /// <summary>
        ///構造函數
        /// </summary>
        public ScriptEngine()
            : this(ScriptLanguage.JavaScript)
        {
        }

        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="language">腳本類型</param>
        public ScriptEngine(ScriptLanguage language)
        {
            this.msc = new ScriptControlClass();
            this.msc.UseSafeSubset = true;
            this.msc.Language = language.ToString();
            ((DScriptControlSource_Event)this.msc).Error += new DScriptControlSource_ErrorEventHandler(ScriptEngine_Error);
            ((DScriptControlSource_Event)this.msc).Timeout += new DScriptControlSource_TimeoutEventHandler(ScriptEngine_Timeout);
        }

        /// <summary>
        /// 運行Eval方法
        /// </summary>
        /// <param name="expression">表達式</param>
        /// <param name="codeBody">函數體</param>
        /// <returns>返回值object</returns>
        public object Eval(string expression, string codeBody)
        {
            msc.AddCode(codeBody);
            return msc.Eval(expression);
        }

        /// <summary>
        /// 運行Eval方法
        /// </summary>
        /// <param name="language">腳本語言</param>
        /// <param name="expression">表達式</param>
        /// <param name="codeBody">函數體</param>
        /// <returns>返回值object</returns>
        public object Eval(ScriptLanguage language, string expression, string codeBody)
        {
            if (this.Language != language)
                this.Language = language;
            return Eval(expression, codeBody);
        }

        /// <summary>
        /// 運行Run方法
        /// </summary>
        /// <param name="mainFunctionName">入口函數名稱</param>
        /// <param name="parameters">參數</param>
        /// <param name="codeBody">函數體</param>
        /// <returns>返回值object</returns>
        public object Run(string mainFunctionName, object[] parameters, string codeBody)
        {
            this.msc.AddCode(codeBody);
            return msc.Run(mainFunctionName, parameters);
        }

        /// <summary>
        /// 運行Run方法
        /// </summary>
        /// <param name="language">腳本語言</param>
        /// <param name="mainFunctionName">入口函數名稱</param>
        /// <param name="parameters">參數</param>
        /// <param name="codeBody">函數體</param>
        /// <returns>返回值object</returns>
        public object Run(ScriptLanguage language, string mainFunctionName, object[] parameters, string codeBody)
        {
            if (this.Language != language)
                this.Language = language;
            return Run(mainFunctionName, parameters, codeBody);
        }

        /// <summary>
        /// 放棄所有已經添加到 ScriptControl 中的 Script 代碼和對象
        /// </summary>
        public void Reset()
        {
            this.msc.Reset();
        }

        /// <summary>
        /// 獲取或設置腳本語言
        /// </summary>
        public ScriptLanguage Language
        {
            get { return (ScriptLanguage)Enum.Parse(typeof(ScriptLanguage), this.msc.Language, false); }
            set { this.msc.Language = value.ToString(); }
        }

        /// <summary>
        /// 獲取或設置腳本執行時間,單位為毫秒
        /// </summary>
        public int Timeout
        {
            get { return this.msc.Timeout; }
            set { this.msc.Timeout = value; }
        }

        /// <summary>
        /// 設置是否顯示用戶界面元素
        /// </summary>
        public bool AllowUI
        {
            get { return this.msc.AllowUI; }
            set { this.msc.AllowUI = value; }
        }

        /// <summary>
        /// 宿主應用程序是否有保密性要求
        /// </summary>
        public bool UseSafeSubset
        {
            get { return this.msc.UseSafeSubset; }
            set { this.msc.UseSafeSubset = true; }
        }

        /// <summary>
        /// RunError事件激發 www.aiwalls.com
        /// </summary>
        private void OnError()
        {
            if (RunError != null)
                RunError();
        }

        /// <summary>
        /// OnTimeout事件激發
        /// </summary>
        private void OnTimeout()
        {
            if (RunTimeout != null)
                RunTimeout();
        }

        private void ScriptEngine_Error()
        {
            OnError();
        }

        private void ScriptEngine_Timeout()
        {
            OnTimeout();
        }
    }
    /// <summary>
    /// 腳本語言枚舉
    /// </summary>
    public enum ScriptLanguage
    {
        /// <summary>
        /// JScript腳本語言
        /// </summary>
        JScript,

        /// <summary>
        /// VBscript腳本語言
        /// </summary>
        VBScript,

        /// <summary>
        /// JavaScript腳本語言
        /// </summary>
        JavaScript
    }

}
 

二 C#方法

using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;

namespace MyQuery.CSharpScript
{
    /// <summary>
    /// C#字符串表達式 計算引擎
    /// by 賈世義 2012-5-23
    /// </summary>
    public class CsharpEngine
    {
        /// <summary>
        /// C#表達式計算 註意區分大小寫
        /// </summary>
        /// <param name="expression">普通的C#字符串表達式</param>
        /// <returns></returns>
        public object Eval(string expression)
        {
            string CLASSNAME = "Calc";
            string METHODNAME = "Run";

            //  創建編譯器實例。 
            CSharpCodeProvider complier = new CSharpCodeProvider();
            //  設置編譯參數。 
            CompilerParameters cp = new CompilerParameters();
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("system.data.dll");
            cp.ReferencedAssemblies.Add("system.xml.dll");
            cp.GenerateExecutable = false;
            cp.GenerateInMemory = true;

            //  創建動態代碼。 
            StringBuilder code = new StringBuilder();
            code.Append("using System; \n");
            code.Append("using System.Text; \n");
            code.Append("using System.Text.RegularExpressions; \n");
            code.Append("using System.Collections; \n");
            code.Append("using System.Collections.Generic; \n");
            code.Append("using System.Collections.Specialized; \n");
            code.Append("using System.Data; \n");
            code.Append("using System.Xml; \n");
            code.Append("public  class  " + CLASSNAME + "\n");
            code.Append("{\n");
            code.Append("        public  object  " + METHODNAME + "()\n");
            code.Append("        {\n");
            code.Append("                return  " + expression + ";\n");
            code.Append("        }\n");
            code.Append("}");

            //  編譯代碼。 
            CompilerResults cr = complier.CompileAssemblyFromSource(cp, code.ToString());
            if (cr.Errors.HasErrors)
            {
                StringBuilder error = new StringBuilder();
                error.Append("Error Compiling Expression: ");
                foreach (CompilerError err in cr.Errors)
                {
                    error.AppendFormat("{0}\n", err.ErrorText);
                }
                throw new Exception("Error Compiling Expression: " + error.ToString());
            }
            else
            {
                //  獲取編譯後的程序集。 
                Assembly assembly = cr.CompiledAssembly;

                //  動態調用方法。 
                object eval = assembly.CreateInstance(CLASSNAME);
                MethodInfo method = eval.GetType().GetMethod(METHODNAME);
                return method.Invoke(eval, null);
            }
        }
    }
}
 

一套基於配置實現的C#快速開發架構,可應用於信息管理、工作流、OA辦公、門戶網站等系統的開發

 

摘自 適易軟件開發工作室

發佈留言