1. 程式人生 > >WinForm中執行JS代碼(多種方法)

WinForm中執行JS代碼(多種方法)

dom cee services 導入 urn 官網下載 char 解析 應用

方法一

使用微軟官方組件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:\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)]

運行結果:

技術分享圖片

出處:https://www.cnblogs.com/feiyuhuo/p/5474790.html

WinForm中執行JS代碼(多種方法)