.Net执行JavaScript脚本,完成函数调用、变量读取设置、任意代码执行
来源:互联网 发布:java实训报告范文 编辑:程序博客网 时间:2024/06/11 20:49
这个类可以完成函数调用、变量读取设置等等与脚本代码的交互,且每个实例都是独立的互不干扰(默认的VsaEngine.CreateEngine()并非每次都创建新实例)。
using System;using System.Reflection;using System.ComponentModel;using System.Security.Permissions;using Microsoft.JScript;using Microsoft.JScript.Vsa;using Microsoft.Vsa;#pragma warning disable 618namespace NTS.JavaScript{/// <summary>/// JavaScript引擎封装类。脚本中不得重写AddReference、AddNamespace、CallDelegate,否则你会死得很难看。注意:该引擎不支持arguments,且目前尚未找到解决方案。请不要跟我提fast选项,这个我懂的。/// </summary>/// <remarks>/// <code>/// NTSJScriptRunner js=new NTSJScriptRunner();/// js.Eval("alert('中国你好!')");//对话框显示"中国你好!"/// js.Eval("AddReference('System.Windows.Forms');AddNamespace('System.Windows.Forms');");//引用所需的程序集并导入命名空间/// js.Eval("function add(a,b){MessageBox.Show(a+b);}");//定义函数add/// js.Invoke("add",1,2);//对话框显示3/// </code>/// </remarks>public class NTSJScriptRunner : Component{private System.Collections.Hashtable addedAssemblies;private System.Collections.Hashtable addedNamespaces;private VsaEngine engine;private ScriptFunction getVariable;private ScriptFunction setVariable;private ScriptFunction invoker;private ScriptFunction safeInvoker;/// <summary>/// 添加引用的程序集。在脚本中可以调用AddReference来引用新的程序集。/// </summary>/// <param name="assemblyName">程序集名。这里使用的是部分名。例如“System.IO”</param>public void AddReference(String assemblyName){if (String.IsNullOrEmpty(assemblyName) || addedAssemblies.Contains(assemblyName))return;Assembly a = Assembly.LoadWithPartialName(assemblyName);if (a == null)return;String s = a.FullName;foreach (var item in engine.Items){IVsaReferenceItem ri = item as IVsaReferenceItem;if (ri == null)continue;if (ri.AssemblyName == s){s = null;break;}}if (s == null)return;((IVsaReferenceItem)engine.Items.CreateItem(assemblyName, VsaItemType.Reference, VsaItemFlag.None)).AssemblyName = s;addedAssemblies.Add(assemblyName, null);}/// <summary>/// 导入命名空间。在脚本中可以调用AddNamespace来导入新的命名空间。/// </summary>/// <param name="namespase"></param>public void AddNamespace(String namespase){if (String.IsNullOrEmpty(namespase) || addedNamespaces.Contains(namespase))return;try{Import.JScriptImport(namespase, engine);addedNamespaces.Add(namespase, null);}catch { }}/// <summary>/// 调用委托。在脚本中可以调用CallDelegate来调用.Net委托。由于在脚本中直接调用委托时传递了脚本当前闭包作为目标实例,导致错误行为,于是才有了这个方法的存在。/// </summary>/// <param name="deligate"></param>public static void CallDelegate(Delegate deligate, params Object[] args){deligate.DynamicInvoke(args);}private delegate void CallDeligate(Delegate deligate, params Object[] args);protected override void Dispose(bool disposing){if (engine == null)return;base.Dispose(disposing);addedAssemblies.Clear();addedNamespaces.Clear();engine.Close();addedAssemblies = null;addedNamespaces = null;getVariable = null;setVariable = null;invoker = null;safeInvoker = null;engine = null;}class DefaultVsaSite : IVsaSite{// Methods[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]public virtual void GetCompiledState(out byte[] pe, out byte[] debugInfo){pe = this.Assembly;debugInfo = this.DebugInfo;}public virtual object GetEventSourceInstance(string itemName, string eventSourceName){throw new VsaException(VsaError.CallbackUnexpected);}public virtual object GetGlobalInstance(string name){throw new VsaException(VsaError.CallbackUnexpected);}[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]public virtual void Notify(string notify, object optional){throw new VsaException(VsaError.CallbackUnexpected);}// Propertiespublic virtual byte[] Assembly{get{throw new VsaException(VsaError.GetCompiledStateFailed);}}public virtual byte[] DebugInfo{get{return null;}}[PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]public virtual bool OnCompilerError(IVsaError error){throw ((JScriptException)error);}}/// <summary>/// 构造封装器。/// </summary>public NTSJScriptRunner(){addedAssemblies = new System.Collections.Hashtable();addedNamespaces = new System.Collections.Hashtable();if(!DesignMode)try{engine = new VsaEngine(false);engine.InitVsaEngine("NTS.JavaScript.NTSJScriptRunner", new DefaultVsaSite());engine.SetOption("AutoRef", true);getVariable = (ScriptFunction)Eval(@"(function(name){return this[name];});");setVariable = (ScriptFunction)Eval(@"(function(name,value){this[name]=value;});");invoker = (ScriptFunction)Eval(@"(function(A7104FA513E04696,A7104FA513E04697,A7104FA513E04698){return eval(A7104FA513E04696+'('+A7104FA513E04697+')','unsafe');});");safeInvoker = (ScriptFunction)Eval(@"(function(A7104FA513E04696,A7104FA513E04697,A7104FA513E04698){return eval(A7104FA513E04696+'('+A7104FA513E04697+')');});");AddReference("System.Windows.Forms");AddNamespace("System.Windows.Forms");SetVariable("A7104FA513E04699", this);SetVariable("CallDelegate", (CallDeligate)CallDelegate);Eval("function AddReference(s){A7104FA513E04699.AddReference(s);}");Eval("function AddNamespace(s){A7104FA513E04699.AddNamespace(s);}");Eval("function alert(s){System.Windows.Forms.MessageBox.Show(s);}");}catch (Exception){}}/// <summary>/// 获取全局变量。变量不存在时返回null。/// </summary>/// <param name="name"></param>/// <returns></returns>public Object GetVariable(String name){return getVariable.Invoke(null, name);}/// <summary>/// 设置全局变量。/// </summary>/// <param name="name"></param>/// <param name="value"></param>/// <returns></returns>public Object SetVariable(String name, Object value){Object v = getVariable.Invoke(null, name);setVariable.Invoke(null, name, value);return v;}/// <summary>/// 在完全信任上下文中调用脚本中的函数。/// </summary>/// <param name="code"></param>/// <param name="parameters"></param>/// <returns></returns>public Object Invoke(String code, params Object[] parameters){if (String.IsNullOrEmpty(code))return null;String s;if (parameters == null || parameters.Length == 0)s = "";else{String[] ss = new String[parameters.Length];for (Int32 i = 0; i < parameters.Length; i++){ss[i] = "A7104FA513E04698[" + i + "]";}s = String.Join(",", ss);}return invoker.Invoke(null, code, s, parameters);}/// <summary>/// 在完全信任上下文中执行任意代码。/// </summary>/// <param name="code"></param>/// <returns></returns>public Object Eval(String code){if (String.IsNullOrEmpty(code))return null;return Microsoft.JScript.Eval.JScriptEvaluate(code, "unsafe", engine);}/// <summary>/// 在部分信任上下文中调用脚本中的函数。/// </summary>/// <param name="code"></param>/// <param name="parameters"></param>/// <returns></returns>public Object SafeInvoke(String code, params Object[] parameters){if (String.IsNullOrEmpty(code))return null;String s;if (parameters == null || parameters.Length == 0)s = "";else{String[] ss = new String[parameters.Length];for (Int32 i = 0; i < parameters.Length; i++){ss[i] = "A7104FA513E04698[" + i + "]";}s = String.Join(",", ss);}return safeInvoker.Invoke(null, code, s, parameters);}/// <summary>/// 在部分信任上下文中执行任意代码。/// </summary>/// <param name="code"></param>/// <returns></returns>public Object SafeEval(String code){if (String.IsNullOrEmpty(code))return null;return Microsoft.JScript.Eval.JScriptEvaluate(code, engine);}}}
- .Net执行JavaScript脚本,完成函数调用、变量读取设置、任意代码执行
- JavaScript设置代码延时执行
- 页面加载完成执行javascript代码
- java设置linuxshell变量执行脚本
- 任意代码执行
- 任意代码执行漏洞
- .net .cs文件中执行javascript脚本
- Java脚本引擎执行 javascript 代码
- 脚本引擎Rhino执行javascript代码
- 如何让Javascript脚本执行CS函数。
- shell脚本变量执行
- 一种在javascript中执行任意html代码的方法
- JDK8中Java调用Javascript脚本引擎动态定义与执行代码
- .NET调用osql.exe执行sql脚本创建表和存储过程<转> 代码
- JavaScript异常:安全设置不允许在此样式表内执行脚本代码
- 如何设置WebView使得加载网页时能够执行JavaScript脚本中的alert()函数
- 用javascript函数设置延时执行jQuery
- 服务器端执行javascript脚本
- AndroidGUI30:定制按钮
- Android成长之路-Android菜单例子小解(3)
- Android成长之路-Android菜单例子小解(4)
- play读取配置文件的方法
- li dl
- .Net执行JavaScript脚本,完成函数调用、变量读取设置、任意代码执行
- java 中静态代码块浅记
- php下载文件方法
- 第一次用了示波器调单片机串口
- C++中虚函数的作用(多态的原理)
- C++多态技术
- 互联网步入社交时代 开放平台渐成SNS网站趋势
- 121. Don't trouble trouble until trouble troubles you. 不要自找麻烦
- ALSA声音编程介绍(译文)