/// <summary> /// Called when a new message is received from a different process. Do not keep a /// reference to or attempt to access the message outside of this callback. /// </summary> protected internal virtual void OnCefProcessMessageReceived(CefProcessMessageReceivedEventArgs e) { if (e.SourceProcess == CefProcessId.Renderer) { if (e.Name == XrayResponseKey) { e.Handled = ProcessXrayMessage(e.Message); } } else if (e.SourceProcess == CefProcessId.Browser) { switch (e.Name) { case XrayReleaseKey: ProcessXrayRelease(e); return; case XrayRequestKey: ProcessXrayRequest(e); return; } } if (!e.Handled) { CefProcessMessageReceived?.Invoke(this, e); } }
private static void ProcessXrayRelease(CefProcessMessageReceivedEventArgs e) { using (var args = e.Message.ArgumentList) { if (args.GetType(0) != CefValueType.Binary) { return; } XrayHandle handle = XrayHandle.FromCfxBinaryValue(args.GetBinary(0)); if ((int)(handle.frame >> 32) != (int)(e.Frame.Identifier >> 32)) { return; // Mismatch process IDs } handle.Release(); } }
private static void ProcessXrayRequest(CefProcessMessageReceivedEventArgs e) { CefListValue args = e.Message.ArgumentList; CefProcessMessage message = new CefProcessMessage(XrayResponseKey); CefListValue retArgs = message.ArgumentList; retArgs.SetSize(2); retArgs.SetValue(0, args.GetValue(0)); CefValue retval = null; XrayAction queryAction = (XrayAction)args.GetInt(1); try { CefV8Context v8Context; XrayObject target = null; if (queryAction == XrayAction.GetGlobal) { v8Context = e.Frame.V8Context; } else { target = XrayHandle.FromCfxBinaryValue(args.GetBinary(2)).GetTarget(e.Frame); v8Context = target?.Context ?? e.Frame.V8Context; } if (!v8Context.IsValid) { throw new ObjectDeadException(); } if (!v8Context.Enter()) { throw new ObjectDeadException(); } try { CefV8Value rv = null; switch (queryAction) { case XrayAction.Get: long corsRid = ScriptableObjectProvider.Get(v8Context, target, args, out rv); if (corsRid != 0) { var xray = new XrayHandle(); xray.dataType = XrayDataType.CorsRedirect; xray.iRaw = corsRid; retval = new CefValue(); retval.SetBinary(xray.ToCfxBinaryValue()); retArgs.SetValue(1, retval); } break; case XrayAction.Set: ScriptableObjectProvider.Set(v8Context, target, args); break; case XrayAction.InvokeMember: rv = ScriptableObjectProvider.InvokeMember(v8Context, target, args); break; case XrayAction.Invoke: rv = ScriptableObjectProvider.Invoke(v8Context, target, args); break; case XrayAction.GetGlobal: rv = v8Context.GetGlobal(); break; default: throw new NotSupportedException(); } if (rv != null) { retval = ScriptableObjectProvider.CastCefV8ValueToCefValue(v8Context, rv, out bool isXray); if (!isXray) { rv.Dispose(); } retArgs.SetValue(1, retval); } } finally { v8Context.Exit(); } } catch (AccessViolationException) { throw; } catch (OutOfMemoryException) { throw; } catch (Exception ex) { //File.AppendAllText("G:\\outlog.txt", ex.GetType().Name + ": " + ex.Message + "\r\n" + ex.StackTrace + "\r\n"); retArgs.SetSize(4); retArgs.SetString(1, ex.Message); retArgs.SetString(2, ex.GetType().FullName); retArgs.SetString(3, ex.StackTrace); } //CfxValueType t = e.Message.ArgumentList.GetType(0); e.Frame.SendProcessMessage(CefProcessId.Browser, message); message.Dispose(); retval?.Dispose(); e.Handled = true; }