1. 程式人生 > >C# 用XiliumCefGlue做瀏覽器,JS和C#相互調用

C# 用XiliumCefGlue做瀏覽器,JS和C#相互調用

需要 更改 net 執行 關於 我的電腦 thread alt 添加

原文:C# 用XiliumCefGlue做瀏覽器,JS和C#相互調用

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u013564470/article/details/78395984

目錄:

  • 目錄
    • XiliumCefGlue初始化最精簡Demo
    • XiliumCefGlueJS調用C代碼
    • XiliumCefGlueC調用JS代碼無返回值
    • XiliumCefGlueC調用JS代碼有返回值



XiliumCefGlue初始化,最精簡Demo

XiliumCefGlue源碼地址
Xilium.CefGlue手冊【百度網盤下載,密碼:j093】
【推薦】XiliumCefGlueDemo 2.3.0.0(吾樂吧軟件站原創)
以上鏈接是參考資料!此例程中本著精簡易懂的原則,把很多不需要的東西去掉,包括try等檢查代碼。下面開始步入正題。

1.解壓壓縮包得到下列文件。選擇需要的文件復制到自己工程【pdb為調試生成文件不需要】,之後將【Xilium.CefGlue】和【Xilium.CefGlue.WindowsForms】添加到引用。
技術分享圖片
只選取了一部分需要的文件放到Debug文件夾下。
技術分享圖片
2.其中Form.cs中代碼如下,添加panl控件讓瀏覽器嵌入其中。Form1_Load的引用在Form1.Designer.cs中。代碼中的網址 http://www.e0575.com/web/ie6bye/test/是對CSS3進行測試的網頁。

using System.Windows.Forms;

using Xilium.CefGlue;
using Xilium.CefGlue.WindowsForms;
namespace XCdemo
{
    public partial class Form1 : Form
    {
        CefWebBrowser browser = new CefWebBrowser();
        public Form1()
        {
            InitializeComponent();
            Form1_Load();
        }
        private
void Form1_Load() { browser.Dock = DockStyle.Fill; browser.StartUrl = @"http://www.e0575.com/web/ie6bye/test/"; panel1.Controls.Add(browser); } } }

3.其中Program.cs中的代碼要做更改,要在程序啟動前初始化。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using Xilium.CefGlue;

namespace XCdemo
{
    static class Program
    {
        /// <summary>
        /// 應用程序的主入口點。
        /// </summary>
        [STAThread]
        private static void Main(string[] args)
        {
            CefRuntime.Load();
            var mainArgs = new CefMainArgs(args);
            var app = new DemoApp();
            var exitCode = CefRuntime.ExecuteProcess(mainArgs, app);
            var settings = new CefSettings
            {
                SingleProcess = false,
                MultiThreadedMessageLoop = true,
                LogSeverity = CefLogSeverity.Disable,
                LogFile = "CefGlue.log",             
            };
            CefRuntime.Initialize(mainArgs, settings, app);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (!settings.MultiThreadedMessageLoop)
            {
                Application.Idle += (sender, e) => { CefRuntime.DoMessageLoopWork(); };
            }
            Application.Run(new Form1());
            CefRuntime.Shutdown();
        }
        internal sealed class DemoApp : CefApp
        {
            protected override void OnBeforeCommandLineProcessing(string processType, CefCommandLine commandLine)
            {
                ;
            }
        }
    }
}

4.在程序運行前,把項目的平臺目標更改為X86之後運行。
代碼下載鏈接http://download.csdn.net/download/u013564470/10046278
技術分享圖片



Xilium.CefGlue,JS調用C#代碼

1.Xilium.CefGlue中JS調用C#比較繁瑣。需要通過反射機制註冊c#函數到JS。因為涉及到的文件較多,而且已經和別的代碼混在一起就不一一列舉了,這裏只列舉關鍵部分。詳細參考第2篇:Xilium CefGlue 關於 CLR Object 與 JS 交互類庫封裝報告:導航篇

public CefV8Handler Cef;
//通過反射機制 註冊c#函數到JS
public void RegisterJs()
{
    JsEvent js = new JsEvent();
    Cef = new CefJsV8Handler(js);
    string javascriptCode = CefJavaScriptEx.CreateJsCodeByObject(js, "Cef");
    CefRuntime.RegisterExtension("Cef", javascriptCode, Cef);
}
protected override void OnWebKitInitialized()
{
    //註冊JS函數
    RegisterJs();
}
public class JsEvent
{
    public Object MyParam { get; set; }
    public Object GetMyParam(){
        if (MyParam.GetType().IsArray){
            String s = "[";
            Object[] o = (Object[])MyParam;
            for (int i = 0; i < o.Length; i++){
                s += "‘" + o[i].ToString() + "‘";
                if (i < (o.Length - 1))
                    s += ",";
            }
            s += "]";
            return s;
        }
        return MyParam;
    }
    [DllImport("User32.dll", EntryPoint = "SendMessage")]
    private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
    [DllImport("User32.dll", EntryPoint = "FindWindow")]
    private static extern int FindWindow(string lpClassName, string lpWindowName);  
    public void openMyPc(String dir){
        if( dir == null)
            dir = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
        Process.Start("explorer.exe", dir);
    }
}

上述代碼功能為,執行JS頁面的代碼,調用C#的函數,打開指定的文件夾,參數為空時打開我的電腦。
技術分享圖片
技術分享圖片



Xilium.CefGlue,C#調用JS代碼(無返回值)

相對於JS調用C#函數,C#調用JS函數就簡單多了。直接調用封裝的庫函數即可,不過此函數之恩那個調用JS函數卻不能獲得JS函數的返回值。代碼如下:

CefFrame frame = browser.Browser.GetMainFrame();
String js = "test();";
if (js.Length > 1)
{
    frame.ExecuteJavaScript(js, frame.Url, 0);
}

上述代碼為調用JS頁面的test()函數,函數圓形如下:

function test(){
    alert("C#中調用了此函數!");
}

當C#中運行代碼時,瀏覽器頁面會彈窗提示“C#中調用了此函數!”。

技術分享圖片
技術分享圖片



Xilium.CefGlue,C#調用JS代碼(有返回值)

很多時候當我們用C#調用JS函數時,需要JS給的返回值。然而封裝的函數卻不具備此功能。這時候我們需要把JS調用C#和C#調用JS結合起來實現JS和C#互調。思路如下,C#調用JS函數,函數的返回值調用C#函數,由於JS調用C#函數是一個新的實例,所以我們需要進程間通信,將得到的信息傳回給主程序。主要代碼為註冊下列C#函數到JS。

const int WM_COPYDATA = 0x004A;
public void JS2C(String dir)
{
    int hWnd = FindWindow(null, @"JS和c#代碼互調");
    if (hWnd == 0)
    {
        MessageBox.Show("555,未找到消息接受者!");
    }
    else
    {
        byte[] sarr = System.Text.Encoding.Default.GetBytes(dir);
        int len = sarr.Length;
        COPYDATASTRUCT cds;
        cds.dwData = (IntPtr)Convert.ToInt16(1);//可以是任意值  
        cds.cbData = len + 1;//指定lpData內存區域的字節數  
        cds.lpData = dir;//發送給目標窗口所在進程的數據  
        SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
    }
}

JS中代碼如下

function testreturn(a){
    var str = "返回值:";
    str = str + a;
    return Cef.JS2C(str);
}

之後我們正常調用ExecuteJavaScript函數即可。效果如下:
技術分享圖片


C# 用XiliumCefGlue做瀏覽器,JS和C#相互調用