码迷,mamicode.com
首页 > Windows程序 > 详细

C# WinForm程序执行JS代码的多种方法

时间:2016-05-09 18:36:47      阅读:1740      评论:0      收藏:0      [点我收藏+]

标签:

方法一

使用微软官方组件Interop.MSScriptControl

1.msscript.ocx下载的地址   http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=D05FCF37-4D9F-4769-9442-0BCEEF907033

   或者点击此处下载 Interop.MSScriptControl.dll

2.项目中引用 msscript.ocx 或者 Interop.MSScriptControl.dll

现在通过这个组件的一些方法来执行JS代码,并接收方法执行后的返回值,实现代码如下:

 

ScriptControlClass sc = new ScriptControlClass(); //申明变量
sc.UseSafeSubset = true; //允许执行不安全的代码
sc.Language = "JavaScript"; //表示需要解析的语言为JavaScript
sc.AddCode(Properties.Resources.GetTimes); // Properties.Resources 资源文件
string str = sc.Run("time", new object[] { "time()" }).ToString();  //第一个参数为要执行的方法名,第二个参数为方法体的传入参数,特别注意的是当JS方法中没有传入参数时,这时传递的为该方法名称,不填写的话会抛异常。然后将JS方法执行后的返回结果存储在变量str中

 

以下的代码将组件常用属性和方法封装成单独的类,方便调用。 

 

using System;
using MSScriptControl;
using System.Text;

//导入js文件,导入js 方法字符串,然后执行js方法。 通过msscript.ocx控件执行JS脚本 ,先引用  Interop.MSScriptControl.dll
//官网下载: 然后  引用 xxx.ocx就行了  http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=D05FCF37-4D9F-4769-9442-0BCEEF907033
namespace csharp中执行js方法
{
    class script_run
    {
        /// <summary>
        /// 脚本类型
        /// </summary>
        public enum ScriptLanguage
        {

            /// <summary>
            /// JScript脚本语言
            /// </summary>
            JScript,
            /// <summary>
            /// VBscript脚本语言
            /// </summary>
            VBscript,
            /// <summary>
            /// JavaScript脚本语言
            /// </summary>
            JavaScript

        }
        /// <summary>
        /// 脚本运行错误代理
        /// </summary>
        public delegate void RunErrorHandler();
        /// <summary>
        /// 脚本运行超时代理
        /// </summary>
        public delegate void RunTimeoutHandler();
        /// <summary>
        /// ScriptEngine类
        /// </summary>
        public class ScriptEngine
        {
            private ScriptControl msc;
            /// <summary>
            /// 定义脚本运行错误事件
            /// </summary>
            public event RunErrorHandler RunError;
            /// <summary>
            /// 定义脚本运行超时事件
            /// </summary>
            public event RunTimeoutHandler RunTimeout;

            /// <summary>
            ///构造函数 默认为 VBscript 脚本类型
            /// </summary>
            public ScriptEngine()
                : this(ScriptLanguage.VBscript)
            { }
            /// <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(OnError);
                ((DScriptControlSource_Event)this.msc).Timeout += new DScriptControlSource_TimeoutEventHandler(OnTimeout);
            }

            /// <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">入口函数名称 例如:add</param>
            /// <param name="parameters">参数:例如:new object(){"",""}</param>
            /// <param name="codeBody">函数体 例如:fucniton add(int a,int b){return a+b;}</param>
            /// <returns>返回值object:获取object.Tostring()</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 0; }
            }

            /// <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();
            }
        }


    }
}

 

缺点: 

1、必须要添加微软官方组件Interop.MSScriptControl

2、不支持开发x64的程序

 

方法二

利用反射获取组件

无需引用其它dll文件,实现代码如下:

 

        /// <summary>
        /// 获取JS时间戳 13位
        /// </summary>
        /// <returns></returns>
        public string GetTimeByJs()
        {
            Type obj = Type.GetTypeFromProgID("ScriptControl");
            if (obj == null) return null;
            object ScriptControl = Activator.CreateInstance(obj);
            obj.InvokeMember("Language", BindingFlags.SetProperty, null, ScriptControl, new object[] { "JavaScript" });
            string js = "function time(a, b, msg){ var sum = a + b; return new Date().getTime() + ‘: ‘ + msg + ‘ = ‘ + sum }";
            obj.InvokeMember("AddCode", BindingFlags.InvokeMethod, null, ScriptControl, new object[] { js });
            return obj.InvokeMember("Eval", BindingFlags.InvokeMethod, null, ScriptControl, new object[] { "time(eval(a), eval(b), ‘a + b‘)" }).ToString();
        }    

 

注意事项:在JS方法中传递非运算使用的参数,参数需要使用单引号括起来,如果传递的参数需要运算,可通过使用eval(‘数字参数‘)的形式进行传递,这样在JS方法中进行计算时,传入的数字参数就不会被解析成字符串,而是转换为字符串对应的数字。

 

C# WinForm程序执行JS代码的多种方法

标签:

原文地址:http://www.cnblogs.com/feiyuhuo/p/5474790.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!