• CefGlue 学习杂记


    1. hg clone代码回来后,还要下载对应的cef dll .  从http://xilium.bitbucket.org/cefglue/ 选择对应的.

      然后把dll和resource目录里的内容都考到debug目录里才能运行.

    2.不能使用 Enable the Visual Studio hosting process 来运行. 因为还会启动2个进程. 这两个进程是相同的exe只是命令行不同, 如果使用了 hosting process ,那么就不能启动另外两个进程.

        调试的时候把所有的项目类型从framework 2.0 3.5 统一到4.0 调试断点才管用. 

        由于chrome是多进程运行, 有时候分不清楚代码是在哪个进程中运行, 所以断点很难下.

         建议用Windbg 打开exe 并且 Debug child processes also ,来调试. 代码里用Console.WriteLine message的形式来看是否执行到.

    3. Js 于Clr 交互:

      可以为window注册一个external:  

     1 private ClrObjectAv8Handler m_extantHandler =new JavaScriptExtMethod();
     2 protected override void OnContextCreated(CefBrowser browser, CefFrame frame, CefV8Context context)
     3  {
     4       var global = context.GetGlobal();
     5 
     6      var extent = CefV8Value.CreateObject(null);
     7 
     8      global.SetValue("external", extent, CefV8PropertyAttribute.None);
     9      AddMethodToJSObject(this.m_extantHandler, extent);
    10 }
    11 //用反射的把所有公共方法注册到js object
    12   public static void AddMethodToJSObject(CefV8Handler hendlerObj, CefV8Value extent)
    13   {
    14             Type t = hendlerObj.GetType();
    15             var functions = t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
    16 
    17             foreach (var m in functions)
    18             {
    19                     string funName =m.Name;
    20 
    21                     extent.SetValue(funName, CefV8Value.CreateFunction(m.Name, hendlerObj), CefV8PropertyAttribute.None);
    22 
    23             }
    24 
    25 }

      

    JavaScriptExtMethod 继承CefV8Handler 重载方法Execute. 
     1   protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception)
     2   {
     3 
     4             exception = null;
     5             try
     6             {
     7                 List<object> paras = V8ValueClrMap.ConvertToClrParameters(arguments);
     8                 Type t = this.GetType();
     9 
    10                 var function = t.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod |
    11                     BindingFlags.IgnoreCase | BindingFlags.DeclaredOnly);
    12                 if (function != null)
    13                 {
    14                     var objRst = function.Invoke(this, paras.Count == 0 ? null : paras.ToArray());
    15                     if (objRst is CefV8Handler)
    16                     {
    17                         returnValue = CefV8Value.CreateObject(null);
    18                         AddMethodToJSObject(objRst as CefV8Handler, returnValue);
    19                     }
    20                     else
    21                     {
    22 
    23                         returnValue = V8ValueClrMap.ConvertToV8Value(objRst);
    24                     }
    25                 }
    26                 else
    27                 {
    28                     exception = "Method no find:"+name;
    29                     returnValue = CefV8Value.CreateString("");
    30                     var message3 = CefProcessMessage.Create("Exception");
    31                     message3.Arguments.SetString(0, exception);
    32                     var success2 = Browser.SendProcessMessage(CefProcessId.Browser, message3);
    33 
    34                     return true;
    35                 }
    36                 return true;
    37             }
    38             catch (Exception ee)
    39             {
    40                 returnValue = CefV8Value.CreateString("");
    41                 exception = ee.Message;
    42                 
    43                 returnValue = CefV8Value.CreateString("");
    44                 var message3 = CefProcessMessage.Create("Exception");
    45                 message3.Arguments.SetString(0, ee.ToString());
    46                 var success2 = Browser.SendProcessMessage(CefProcessId.Browser, message3);
    47 
    48                 return true;
    49             }
    50             
    51         }

    再实现一个V8Value与Clr的对应.

     1 public class V8ValueClrMap
     2     {
     3         public static List<object> ConvertToClrParameters(CefV8Value[] arguments)
     4         {
     5             List<object> rtn = new List<object>();
     6             if (arguments == null || arguments.Length == 0)
     7             {
     8                 return rtn;
     9             }
    10             foreach (var v in arguments)
    11             {
    12                 rtn.Add(GetClrValue(v));
    13             }
    14             return rtn;
    15         }
    16         public static object GetClrValue(CefV8Value v)
    17         {
    18             if (v.IsArray)
    19             {
    20                 int length = v.GetArrayLength();
    21                 object[] objs = new object[length];
    22                 for (int i = 0; i < length; i++)
    23                 {
    24                     var value = v.GetValue(i);
    25                     objs[i] = GetClrValue(value);
    26                 }
    27                 return objs;
    28             }
    29 
    30             if (v.IsBool ) return v.GetBoolValue();
    31             
    32             if (v.IsDate) return v.GetDateValue();
    33             if (v.IsInt) return v.GetIntValue();
    34 
    35             if (v.IsDouble) return v.GetDoubleValue();
    36             
    37             if (v.IsFunction){
    38                 throw new NotSupportedException("IsFunction");
    39             }
    40 
    41             
    42             if (v.IsNull) return null;
    43             if (v.IsObject)
    44             {
    45                 //throw new NotSupportedException("IsObject");
    46                 var map = v.GetUserData() as Clr2V8ValueWrapper;
    47                 if (map != null)
    48                     return map.ClrObject;
    49                 return null;
    50             }
    51             if (v.IsString) return v.GetStringValue();
    52             if (v.IsUInt) return v.GetUIntValue();
    53             if (v.IsUndefined) return null;
    54             if (v.IsUserCreated)
    55             {
    56                 throw new NotSupportedException("IsUserCreated");
    57             }
    58             throw new NotSupportedException("??");
    59             
    60         }
    61 
    62         public static CefV8Value ConvertToV8Value(object o)
    63         {
    64             if (o == null) return CefV8Value.CreateUndefined();
    65             if (o is bool) return CefV8Value.CreateBool((bool)o);
    66             if (o is DateTime) return CefV8Value.CreateDate((DateTime)o);
    67             if (o is double) return CefV8Value.CreateDouble((double)o);
    68             if (o is int) return CefV8Value.CreateInt((int)o);
    69             if (o is string) return CefV8Value.CreateString((string)o);
    70             if (o is uint) return CefV8Value.CreateUInt((uint)o);
    71             if (o is Array)
    72             {
    73                 var a=(Array)o;
    74                 var rtn = CefV8Value.CreateArray(a.Length);
    75                 for(int i=0;i<a.Length;i++)
    76                 {
    77                     rtn.SetValue(i,ConvertToV8Value(a.GetValue(i)));
    78                 }
    79                 return rtn;
    80             }
    81             if (o is System.Collections.IList)
    82             {
    83                 var a = (System.Collections.IList)o;
    84                 var rtn = CefV8Value.CreateArray(a.Count);
    85                 for (int i = 0; i < a.Count; i++)
    86                 {
    87                     rtn.SetValue(i, ConvertToV8Value(a[i]));
    88                 }
    89                 return rtn;
    90             }
    91             throw new NotSupportedException("??");
    92         }
    93     }
    然后就可以在js里调用JavaScriptExtMethod的方法: window.external.SomeMethod();

    C# 里调用Js方法, 推荐使用发Message 到Render进程, 然后render进程执行完后再发消息给browser进程的方法.这样才能方便的捕获到js里的异常和返回值.

    render进程:
     1 protected override bool OnProcessMessageReceived(CefBrowser browser, CefProcessId sourceProcess, CefProcessMessage message)
     2         {
     3             if (message.Name == "ExecuteJavaScript")
     4             {
     5                 string code = message.Arguments.GetString(0);
     6                 var context = browser.GetMainFrame().V8Context;
     7                 context.Enter();
     8                 try
     9                 {
    10                     var global = context.GetGlobal();
    11                     var evalFunc = global.GetValue("eval");
    12                     CefV8Value arg0 = CefV8Value.CreateString(code);
    13 
    14                     var rtn = evalFunc.ExecuteFunctionWithContext(context, evalFunc,
    15                         new CefV8Value[] { arg0 });
    16                     if (evalFunc.HasException)
    17                     {
    18                         var exception = evalFunc.GetException();
    19                         var message3 = CefProcessMessage.Create("Exception");
    20                         var arguments = message3.Arguments;
    21                         arguments.SetString(0, exception.Message + " At Line" + exception.LineNumber);
    22                         var success2 = browser.SendProcessMessage(CefProcessId.Browser, message3);
    23 
    24                     }
    25                     else
    26                     {
    27                         var message3 = CefProcessMessage.Create("JavascriptExecutedResult");
    28                         var arguments = message3.Arguments;
    29                         arguments.SetString(0,rtn.GetStringValue());
    30                         var success2 = browser.SendProcessMessage(CefProcessId.Browser, message3);
    31                     }
    32                 }
    33 
    34                 finally
    35                 {
    36                     context.Exit();
    37                 }
    38             }
    39 
    40             
    41 
    42             return false;
    43         }

      4. javascript 的执行都在renderer 的Main Thread 上面. 




  • 相关阅读:
    可遇不可求的Question之无法加载 DLL
    可遇不可求的Question之mysql odbc 5.1 driver 指定驱动程序无法加载
    可遇不可求的Question之Got error 127 from table handler
    可遇不可求的Question之Odbc与MYSQLCLIENT转码机制探讨
    【转】Task Scheduler Managed Wrapper: 由程式來排程工作
    可遇不可求的Question之update from 语法
    【转】Long Time Operations in ASP.NET
    可遇不可求的Question之System.TypeLoadException错误
    浅谈Asp.Net中涉及到的四个TimeOut属性
    4月2号
  • 原文地址:https://www.cnblogs.com/huigll/p/3513408.html
Copyright © 2020-2023  润新知