WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互
2021-04-14 05:29
YPE html>
标签:显示 uri box tla mod runtime share 官方 定义
原文地址: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
{
///
/// 脚本类型
///
public enum ScriptLanguage
{
///
/// JScript脚本语言
///
JScript,
///
/// VBscript脚本语言
///
VBscript,
///
/// JavaScript脚本语言
///
JavaScript
}
///
/// 脚本运行错误代理
///
public delegate void RunErrorHandler();
///
/// 脚本运行超时代理
///
public delegate void RunTimeoutHandler();
///
/// ScriptEngine类
///
public class ScriptEngine
{
private ScriptControl msc;
///
/// 定义脚本运行错误事件
///
public event RunErrorHandler RunError;
///
/// 定义脚本运行超时事件
///
public event RunTimeoutHandler RunTimeout;
///
///构造函数 默认为 VBscript 脚本类型
///
public ScriptEngine()
: this(ScriptLanguage.VBscript)
{ }
///
/// 构造函数
///
/// 脚本类型
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);
}
///
/// 运行Eval方法
///
/// 表达式
/// 函数体
/// 返回值object
public object Eval(string expression, string codeBody)
{
msc.AddCode(codeBody);
return msc.Eval(expression);
}
///
/// 运行Eval方法
///
/// 脚本语言
/// 表达式
/// 函数体
/// 返回值object
public object Eval(ScriptLanguage language, string expression, string codeBody)
{
if (this.Language != language)
this.Language = language;
return Eval(expression, codeBody);
}
///
/// 运行Run方法
///
/// 入口函数名称 例如:add
/// 参数:例如:new object(){"",""}
/// 函数体 例如:fucniton add(int a,int b){return a+b;}
/// 返回值object:获取object.Tostring()
public object Run(string mainFunctionName, object[] parameters, string codeBody)
{
this.msc.AddCode(codeBody);
return msc.Run(mainFunctionName, parameters);
}
///
/// 运行Run方法
///
/// 脚本语言
/// 入口函数名称
/// 参数
/// 函数体
/// 返回值object
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 0; }
}
///
/// 设置是否显示用户界面元素
///
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();
}
}
}
}

缺点:
1、必须要添加微软官方组件Interop.MSScriptControl
2、不支持开发x64的程序
方法二
利用反射获取组件(推荐使用)
无需引用其它dll文件,实现代码如下:

////// 获取JS时间戳 13位 /// ///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文件的代码如下:


忽略脚本错误,设置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代码:


注意的地方:记得给公开对象加上以下标签属性
[PermissionSet(SecurityAction.Demand, Name ="FullTrust")] [ComVisible(true)]
运行结果:

WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互
标签:显示 uri box tla mod runtime share 官方 定义
原文地址:https://www.cnblogs.com/xishi/p/8967478.html
文章标题:WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互
文章链接:http://soscw.com/essay/75531.html