现在的位置: 首页 > 综合 > 正文

C#字符串表达式计算 C#运行脚本

2013年01月25日 ⁄ 综合 ⁄ 共 7660字 ⁄ 字号 评论关闭

一直以来一直使用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事件激发
        /// </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办公、门户网站等系统的开发

演示地址:http://121.18.78.216/

抱歉!评论已关闭.