WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互
方法一
使用微软官方组件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 ; }
- }
- /// <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:\Users\Administrator\Desktop\abc.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)]
运行结果:
WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互的更多相关文章
- WinForm中执行JS代码(多种方法)
方法一 使用微软官方组件Interop.MSScriptControl 1.msscript.ocx下载的地址 http://www.microsoft.com/downloads/details ...
- js 代码大全(各种方法、属性)
事件源对象event.srcElement.tagNameevent.srcElement.type捕获释放event.srcElement.setCapture(); event.srcElemen ...
- 判断小数点位数不超过2位的JS代码和在删除确认框里面插JS代码
<script type="text/javascript"> function checkDecimals(){ var decallowed = 2; var re ...
- [搜片神器]winform程序自己如何更新自己的方法代码
DHT抓取程序开源地址:https://github.com/h31h31/H31DHTDEMO 数据处理程序开源地址:https://github.com/h31h31/H31DHTMgr 国外测试 ...
- 微信小程序——详细讲解页面传值(多种方法)
1.使用navigator的url带参传值 (1)在pageA页面有一个固定的值要传递到pageB页面,比如说一个固定的值user_id要传递给B <navigator url=".. ...
- 获取网页js代码的一个方法
这个是看了别人的代码,稍加修改而成的.怕时间长忘了,在这里记一笔: console.log(require(["foo:bar.js"]).prototype.someMethod ...
- winform程序开机自动启动代码
几天前头儿要我实现程序能开机自动启动,搞好了,整理起来写下来. private void checkBox1_CheckedChanged(object sender, EventArgs e) { ...
- highlight.js代码风格引入方法
<link href="https://cdn.bootcss.com/highlight.js/9.15.10/styles/darcula.min.css" rel=&q ...
- 关于后台执行JS代码总结
方法一.FineUI的 pagecontext对象 string js="functionName();"; PageContext.RegisterStartUpScript(j ...
随机推荐
- linux权限补充:rwt rwT rws rwS 特殊权限
众所周知,Linux的文件权限如: 777:666等,其实只要在相应的文件上加上UID的权限,就可以用到加权限人的身份去运行这个文件.所以我们只需要将bash复制出来到另一个地方,然后用root加上U ...
- linux命令学习(一)—— 文件和目录管理命令
首先需要知道的是命令提示符 [root@localhost ~] # 当前登录用户(root) 主机名(localhost) 当前所在目录(家目录) 超级用户提示符(#) 普通用户提示符($) 1.1 ...
- docker-5 docker仓库
docker部署环境:CentOS release 6.5 (Final) Docker配置文件:/etc/sysconfig/docker 重要参数解释: -H 表示Docker Daemon绑定 ...
- netbeans设置语言
netbeans的界面语言 默认是按系统语言 设的. 想要自己指定的话,加上以下参数就可以了. 中文 --locale zh:CN 英文 --locale en:US 日文 --locale ja:J ...
- Android Studio中使用android:src="@drawable/ic_launcher"报错
今天尝试着安装了Android Studio,界面确实不错,列表什么的也改了很多. 然后新建工程,习惯性在activity_main那里加上一段代码测试看看: <ImageView androi ...
- Equinox P2的学习
product.configuration 点击“Add按钮”并添加以下插件: org.eclipse.equinox.p2.ui org.eclipse.equinox.p2.ui.sdk org. ...
- Linux安装Mysql rpm
1.安装时候会提示与已经安装的RPM包有冲突,所以我们先卸载一些RPM包,要卸载哪些呢?我们要卸载的是包含有mariadb关键字的RPM包,执行命令:rpm -qa|grep mariadb来查看一下 ...
- AI (Adobe Illustrator)详细用法(二)
本文主要是介绍形状的创建与编辑. 一.系列形状工具 1.矩形工具 矩形的作用很大,比如输入框,按钮,图片的大小,比如相片应用中每一个照片占的比例是多大. 初步的UI图的话,会画矩形和圆角矩形就够了. ...
- [转]SQL Server 高性能写入的一些总结
本文转自:http://www.cnblogs.com/rush/archive/2012/08/31/2666090.html 1.1.1 摘要 在开发过程中,我们不时会遇到系统性能瓶颈问题,而引起 ...
- 【原创Android游戏】--猜数字游戏V1.1 --数据存储,Intent,SimpleAdapter的学习与应用
--------------------------------------------------------------- V0.1版本 上次做完第一个版本后,发现还有一些漏洞,并且还有一些可以添 ...