一直以来一直使用js引擎,也就是MSScript.ocx即Interop.MSScriptControl.dll来实现字符串表达式的计算。
但是周一在部署时发现存在64位不支持的问题,虽然开启32位后解决了,但是心里总是个疙瘩。
昨天利用C#代码编译功能终于解决了C#字符串表达式的计算的问题,方法和代码都来自互联网,非常感谢,也把自己修改后的分享给大家
一、脚本方法
using System;
using System.Collections.Generic;
using System.Text;
using MSScriptControl;
namespace MyQuery.CSharpScript
{
///
/// 脚本运行错误代理
///
public delegate void RunErrorHandler();
///
/// 脚本运行超时代理
///
public delegate void RunTimeoutHandler();
///
/// 脚本处理引擎
/// by 开源盛世-源代码下载网 基于网络文章整理开发,是学习自定义脚本的产物
///
public sealed class ScriptEngine
{
private ScriptControlClass msc;
///
/// 定义脚本运行错误事件
///
public event RunErrorHandler RunError;
///
/// 定义脚本运行超时事件
///
public event RunTimeoutHandler RunTimeout;
///
///构造函数
///
public ScriptEngine()
: this(ScriptLanguage.JavaScript)
{
}
///
/// 构造函数
///
/// 脚本类型
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);
}
///
/// 运行Eval方法
///
/// 表达式
/// 函数体
///
public object Eval(string expression, string codeBody)
{
msc.AddCode(codeBody);
return msc.Eval(expression);
}
///
/// 运行Eval方法
///
/// 脚本语言
/// 表达式
/// 函数体
///
public object Eval(ScriptLanguage language, string expression, string codeBody)
{
if (this.Language != language)
this.Language = language;
return Eval(expression, codeBody);
}
///
/// 运行Run方法
///
/// 入口函数名称
/// 参数
/// 函数体
///
public object Run(string mainFunctionName, object[] parameters, string codeBody)
{
this.msc.AddCode(codeBody);
return msc.Run(mainFunctionName, parameters);
}
///
/// 运行Run方法
///
/// 脚本语言
/// 入口函数名称
/// 参数
/// 函数体
///
public object Run(ScriptLanguage language, string mainFunctionName, object[] parameters, string codeBody)
{
if (this.Language != language)
this.Language = language;
return Run(mainFunctionName, parameters, codeBody);
}
///
/// 放弃所有已经添加到 ScriptControl 中的 Script 代码和对象
///
public void Reset()
{
this.msc.Reset();
}
///
/// 获取或设置脚本语言
///
public ScriptLanguage Language
{
get { return (ScriptLanguage)Enum.Parse(typeof(ScriptLanguage), this.msc.Language, false); }
set { this.msc.Language = value.ToString(); }
}
///
/// 获取或设置脚本执行时间,单位为毫秒
///
public int Timeout
{
get { return this.msc.Timeout; }
set { this.msc.Timeout = value; }
}
///
/// 设置是否显示用户界面元素
///
public bool AllowUI
{
get { return this.msc.AllowUI; }
set { this.msc.AllowUI = value; }
}
///
/// 宿主应用程序是否有保密性要求
///
public bool UseSafeSubset
{
get { return this.msc.UseSafeSubset; }
set { this.msc.UseSafeSubset = true; }
}
///
/// RunError事件激发
///
private void OnError()
{
if (RunError != null)
RunError();
}
///
/// OnTimeout事件激发
///
private void OnTimeout()
{
if (RunTimeout != null)
RunTimeout();
}
private void ScriptEngine_Error()
{
OnError();
}
private void ScriptEngine_Timeout()
{
OnTimeout();
}
}
///
/// 脚本语言枚举
///
public enum ScriptLanguage
{
///
/// JScript脚本语言
///
JScript,
///
/// VBscript脚本语言
///
VBScript,
///
/// JavaScript脚本语言
///
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
{
///
/// C#字符串表达式 计算引擎
/// by 贾世义 2012-5-23
///
public class CsharpEngine
{
///
/// C#表达式计算 注意区分大小写
///
/// 普通的C#字符串表达式
///
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/