ChromiumWebBrowser 使用记录

本文介绍了一个使用C#封装ChromiumWebBrowser控件的实现,包括事件处理、页面加载完成回调、JavaScript对象注入等功能。同时,展示了如何进行性能优化,如禁用GPU、同步帧率等,并提供了简单的使用示例。此外,还提及了可能的启动清单优化,但未详细展开。
摘要由CSDN通过智能技术生成
ChromiumWebBrowser 简单封装

    public partial class CustomChromiumWebBrowser : ChromiumWebBrowser
    {
        public event Action LoadOver;

        public event Action<ConsoleMessageEventArgs> LoadMessage;

        public event Func<object> ResolveObject;

        public CustomChromiumWebBrowser(string url) : base(url)
        {
        	// 可以不要这个事件
            IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;

            Dock = DockStyle.Fill;

            // 跨域
            BrowserSettings.ApplicationCache = CefState.Enabled;
            BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
            BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;

            MenuHandler = new MenuHandlerEx();
            KeyboardHandler = new CEFKeyBoardHander();

            // 页面加载完毕后
            ConsoleMessage += (s, eve) =>
            {
                try
                {
                    // 等待页面 Console.log("ready")   自带的加载完毕事件 没办法等网页加载完之后再执行
                    if (eve.Message == "ready")
                    {
                        LoadOver?.Invoke();
                    }
                    LoadMessage?.Invoke(eve);
                }
                catch (Exception e)
                {
                    Log.ForContext<CustomChromiumWebBrowser>().Error(e,"ready");
                }
            };

            // 注入类到页面
            JavascriptObjectRepository.ResolveObject += (s, eve) =>
            {
                var repo = eve.ObjectRepository;
                if (eve.ObjectName == "cs")
                {
                    object oj = ResolveObject?.Invoke();
                    if (oj != null)
                    {
                        repo.Register("cs", oj, isAsync: true, options: BindingOptions.DefaultBinder);
                    }
                }
            };
        }

        #region Help

        private void OnIsBrowserInitializedChanged(object sender, EventArgs e)
        {
            var b = ((ChromiumWebBrowser)sender);

            //浏览器初始化更改 浏览器获取焦点
            this.InvokeOnUiThreadIfRequired(() => b.Focus());
        }

        /// <summary>
        /// 监听按键
        /// </summary>
        public class CEFKeyBoardHander : IKeyboardHandler
        {
            public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
            {
                if (type == KeyType.KeyUp && Enum.IsDefined(typeof(Keys), windowsKeyCode))
                {
                    var key = (Keys)windowsKeyCode;
                    switch (key)
                    {
                        case Keys.F12:
                            browser.ShowDevTools();
                            break;

                        case Keys.F5:
                            if (modifiers == CefEventFlags.ControlDown)
                            {
                                //ctrl+f5
                                browser.Reload(true);
                            }
                            else
                            {
                                //f5
                                browser.Reload();
                            }
                            break;
                    }
                }
                return false;
            }

            public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
            {
                return false;
            }
        }

        /// <summary>
        /// 禁用右键菜单
        /// </summary>
        public class MenuHandlerEx : IContextMenuHandler
        {
            public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
            {
                model.Clear();
            }

            public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
            {
                return false;
            }

            public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
            {
            }

            public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
            {
                return false;
            }
        }

        #endregion Help
    }

上面 InvokeOnUiThreadIfRequired 方法


    public static class ControlExtensions
    {
        /// <summary>
        /// Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
        /// </summary>
        /// <param name="control">the control for which the update is required</param>
        /// <param name="action">action to be performed on the control</param>
        public static void InvokeOnUiThreadIfRequired(this Control control, Action action)
        {
            //If you are planning on using a similar function in your own code then please be sure to
            //have a quick read over https://stackoverflow.com/questions/1874728/avoid-calling-invoke-when-the-control-is-disposed
            //No action
            if (control.Disposing || control.IsDisposed || !control.IsHandleCreated)
            {
                return;
            }

            if (control.InvokeRequired)
            {
                control.BeginInvoke(action);
            }
            else
            {
                action.Invoke();
            }
        }
    }

简单使用

    public partial class HtmlForm : Form
    {
        private CustomChromiumWebBrowser  _chromiumWebBrowser;

        public HtmlForm()
        {
            InitializeComponent();
        }

        protected override void Init()
        {
            _chromiumWebBrowser = new CustomChromiumWebBrowser ("your url");

            // 加载完毕后调用
            _chromiumWebBrowser.LoadOver += _chromiumWebBrowser_LoadOver;
            // 注入对象
            _chromiumWebBrowser.ResolveObject += ChromiumWebBrowser_ResolveObject;
            // 添加到容器
            panelControl.Controls.Add(_chromiumWebBrowser);
            // 页面中的刷新按钮
            btnRefresh.ItemClick += BtnRefresh_ItemClick;
        }

        /// <summary>
        /// ready 后 调用方法
        /// </summary>
        private void _chromiumWebBrowser_LoadOver()
        {
        	// 调用 网页的方法  比如注入 Token
            _chromiumWebBrowser.ExecuteScriptAsync("EventName", [parameter]);
        }

        /// <summary>
        /// 返回注入对象
        /// </summary>
        /// <returns></returns>
        private object ChromiumWebBrowser_ResolveObject()
        {
            return new JsInteraction();
        }

        public class JsInteraction
        {
            public async Task<bool> openItem(string parameterName)
            {
                // 写一些方法 让网页可以调用 winform  比如打开 winform 的某个页面等
            }
        }

        private void BtnRefresh_ItemClick(object sender, ItemClickEventArgs e)
        {
            //刷新页面
            _chromiumWebBrowser.Reload();
        }
    }

对于网页的一些优化

在 Program 的 Main方法中 开启关闭一些 我也不是特别清楚的的属性


#if ANYCPU
            CefRuntime.SubscribeAnyCpuAssemblyResolver();
#endif
            var cachePath = Path.Combine(Application.StartupPath, "CefSharp\\Cache");

            var settings = new CefSettings();
            settings.CachePath = cachePath;

            /// <summary>
            /// https://github.com/cefsharp/CefSharp/commit/8706aadd3f4d2effc563cc5158734e66639c5293
            /// 设置命令行参数以获得最佳 OSR(Offscreen and WPF) 渲染性能 Swiftshader 将用于 WebGL
            /// </summary>
            //使用软件渲染和合成(禁用 GPU)来提高 FPS 并降低 CPU 使用率
            settings.CefCommandLineArgs.Add("disable-gpu");
            settings.CefCommandLineArgs.Add("disable-gpu-compositing");
            //同步所有进程之间的帧率 通过避免生成额外的帧来降低 CPU 使用率
            settings.CefCommandLineArgs.Add("enable-begin-frame-scheduling");

            //settings.CefCommandLineArgs.Add("enable-media-stream");
            //settings.CefCommandLineArgs.Add("use-fake-ui-for-media-stream");
            //settings.CefCommandLineArgs.Add("enable-usermedia-screen-capturing");
            //settings.UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 6P Build/XXXXX; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/47.0.2526.68 Mobile Safari/537.36";

            //执行依赖项检查以确保所有相关资源都在输出目录中。
            Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

            CefSharpSettings.ConcurrentTaskExecution = true;

app.manifest

在官方Demo中 有看到通过启动清单(app.manifest 文件)去优化ChromiumWebBrowser 这个就不太懂了 有需要自行百度

### 回答1: WPF是一种用于创建Windows桌面应用程序的技术,而CefSharp是一个针对.NET应用程序的Chromium嵌入式浏览器框架。结合使用WPF和CefSharp,我们可以创建一个自定义的浏览器应用程序。 首先,我们需要在WPF项目中添加CefSharp的引用,以便能够使用相关功能和组件。接下来,我们可以在XAML文件中创建一个WebBrowser控件,这个控件将会是我们浏览器应用程序的主要窗口。在代码中,我们可以使用CefSharp的API来配置浏览器的行为,比如加载URL、前进、后退、刷新等操作。 为了实现这些功能,我们需要编写一些C#代码。首先,我们需要初始化CefSharp的设置,并在应用程序启动时进行加载。然后,我们可以在浏览器的事件处理程序中编写代码,以响应用户的行为,例如在URL改变时加载新的页面,或在点击后退按钮时返回上一页。 此外,我们还可以通过使用CefSharp提供的API,实现一些其他的自定义功能。例如,我们可以通过JavaScript与浏览器进行交互,执行一些特定的脚本操作,或者通过注入自定义的CSS样式来修改网页的外观。 总而言之,使用WPF和CefSharp,我们可以创建一个功能强大且自定义的浏览器应用程序。通过灵活运用CefSharp的API,我们可以实现各种浏览器相关的功能,并与用户进行交互。这是一个非常有用且有趣的项目,可以满足用户对浏览器的个性化需求。 ### 回答2: WPF是一种用于创建富客户端应用程序的开发框架,而CEFSharp是基于Chromium内核的用于嵌入式浏览器的开源框架。使用CEFSharp可以很方便地在WPF应用程序中嵌入浏览器功能。 首先,我们需要在WPF应用程序中添加CEFSharp的NuGet包。然后在XAML中创建一个WindowsFormsHost控件,用于嵌入浏览器。接下来,我们可以在代码中用CEFSharp的ChromiumWebBrowser控件来加载和显示网页。 加载一个网页非常简单,只需调用ChromiumWebBrowser的Load方法并传入网页的URL即可。此外,我们还可以注册一些事件来处理浏览器的加载完成、加载进度、错误等情况。例如,可以使用LoadEnd事件来监听页面加载完成,然后执行一些自定义逻辑。 此外,我们还可以通过调用ChromiumWebBrowser的ExecuteScriptAsync方法来在加载的网页中执行JavaScript代码。这使得我们可以通过与网页进行交互,实现一些复杂的功能。 在加载和显示网页时,我们也可以通过相关API来控制浏览器的行为,比如设置代理、禁用/启用JavaScript、禁止弹出窗口等。 总的来说,使用CEFSharp可以很方便地在WPF应用程序中嵌入浏览器功能。无论是显示网页,还是与网页进行交互,都可以通过CEFSharp轻松实现。这为开发者提供了更多的可能性,使得我们可以在WPF应用程序中创造出更加丰富和复杂的浏览器体验。 ### 回答3: WPF(Windows Presentation Foundation)是一种用于开发Windows应用程序的框架,而CefSharp是一个基于谷歌开源项目Chromium Embedded Framework (CEF)的.NET库,它允许在WPF应用程序中嵌入一个完整的浏览器。 使用CefSharp在WPF应用程序中创建一个浏览器可以带来许多好处。首先,由于使用Chromium的底层技术,CefSharp浏览器具有出色的跨平台兼容性和稳定性。它能够处理各种网页内容,包括HTML,CSS,JavaScript和其他多媒体元素。其次,CefSharp提供了强大的API,开发人员可以使用C#编写代码来控制浏览器的行为。这使得对浏览器的定制和扩展变得非常容易。 要在WPF中集成CefSharp浏览器,首先需要将CefSharp的NuGet包添加到项目中。然后,在需要嵌入浏览器的窗体中,可以使用XAML定义一个WebBrowser控件。接下来,在代码中初始化CefSharp,并设置WebBrowser控件的源为所需的URL或页面内容。 开发人员可以使用C#代码与嵌入的浏览器进行交互。例如,可以使用CefSharp的API执行一些常见的浏览器操作,如导航到新的URL,前进和后退浏览历史记录,或者捕获页面上的事件。此外,还可以通过JavaScript与页面进行交互,实现双向通信。 除了基本的浏览功能,CefSharp还提供了一些高级功能,如自定义页面呈现,浏览器扩展和弹出窗口管理。这些功能使得开发人员能够根据需要定制浏览器的外观和行为。 总之,使用CefSharp在WPF应用程序中创建一个浏览器是一种简单而强大的方法,可以使应用程序获得Web浏览功能,并根据需要进行自定义和扩展。无论是实现一个简单的浏览器界面还是构建一个复杂的浏览器应用程序,CefSharp都能提供所需的功能和灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值