• WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互


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

    方法一

    使用微软官方组件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(a, b, 'a + b')" }).ToString();
            }    
    复制代码

    注意事项:在JS方法中传递的参数如果是字符串,参数需要使用引号括起来,否则不需要。

    区别:   

    1、方法一需要引用dll文件,方法二不需要引用dll文件;

    2、方法一不支持开发x64的程序,方法二支持;

    3、执行JS方法时,如果传入的参数是字符串时,在方法二中必须要使用引号括起来,否则不需要,而方法一给JS方法传参无需使用括号。

    方法三

    利用WebBrowser调用空间加密JS直接获取结果

    根据参数自己生成html代码,然后交给WebBrowser执行。html文件的代码如下:

    复制代码
    <!DOCTYPE html>
    <html>
    <script type="text/javascript" src="http://ui.ptlogin2.qzone.com/js/10141/login_10.js"></script>
    <script type="text/javascript" >
            var result=$.Encryption.getEncryption("bada23","","",!1);
            document.write(result);
    </script>
    <body>
    </body>
    </html>
    复制代码

    忽略脚本错误,设置WebBrowser属性:

    C#代码如下:

    复制代码
    void MainFormLoad(object sender, EventArgs e)
    {
        webBrowser1.DocumentText=File.ReadAllText(@"C:UsersAdministratorDesktopabc.html");             
    }
    void Button1Click(object sender, EventArgs e) { MessageBox.Show(webBrowser1.Document.Body.OuterText); }
    复制代码

    效果如下图所示:

    补充

    WebBrowser与JS交互,JS调用C#方法

    以下补充一下如何使用JS调用C#方法

    C#代码:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.IO;
    using System.Runtime.InteropServices;  
    using System.Security.Permissions;
      
    namespace test
    {  
        [PermissionSet(SecurityAction.Demand, Name ="FullTrust")]
        [ComVisible(true)]//COM+组件可见
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
      
            private void button1_Click(object sender, EventArgs e)
            {
                webBrowser1.Document.InvokeScript("Run", new object[] { "CShareFunction" });
            }
              
            private void Form1_Load(object sender, EventArgs e)
            { 
                webBrowser1.ObjectForScripting = this;//具体公开的对象,这里可以公开自定义对象
                webBrowser1.Navigate(Application.StartupPath + "/dom.html"); 
            }
      
            public void ShowMsg(string msg)
            {
                MessageBox.Show(msg);           
            }
        }
    }
    复制代码

    html文件的JS代码:

    复制代码
    <html>
      <head>
      </head>
      <body> 
      </body>     
       <script type="text/javascript" charset="utf-8">
            function Run(str)
           {     
                window.external.ShowMsg(str);
           }
        </script>
    </html>
    复制代码

    注意的地方:记得给公开对象加上以下标签属性

    [PermissionSet(SecurityAction.Demand, Name ="FullTrust")]
    [ComVisible(true)]

    运行结果:

  • 相关阅读:
    nethogs命令执行报异常的解决方法
    性能监控
    Linux图形化监控网络流量:speedometer查看流量
    JMeter监控Slave机器是否执行
    安全测试robots
    在ASP.NET MVC4中实现同页面增删改查,无弹出框02,增删改查界面设计
    在ASP.NET MVC4中实现同页面增删改查,无弹出框01,Repository的搭建
    报错:非介入式客户端验证规则中的验证类型名称必须唯一。下列验证类型出现重复
    ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象
    在ASP.NET MVC中使用Knockout实践09,自定义绑定
  • 原文地址:https://www.cnblogs.com/xishi/p/8967478.html
Copyright © 2020-2023  润新知