CefSharp 内置devtools全屏截图

1 篇文章 0 订阅
1 篇文章 0 订阅

发现多种内核浏览器现在截图结果是一片空白,自己试了一下,自带的WebBrowser可以,但IE内核就算了。直接用CefSharp,发现各种截图都是一片黑,看到了DevToolsExtensions,使用后,发现只能截图一次,第二次就出异常了。Generated MessageId 100002 doesn't match returned Message Id 100001。下载源码,来到DevToolsClient.cs

 public async Task<DevToolsMethodResponse> ExecuteDevToolsMethodAsync(string method, IDictionary<string, object> parameters = null)
        {
            if (browser == null || browser.IsDisposed)
            {
                //TODO: Queue up commands where possible
                return new DevToolsMethodResponse { Success = false };
            }
            Console.WriteLine("lastMessageId:{0}", lastMessageId);
            var messageId = Interlocked.Increment(ref lastMessageId);
            lastMessageId = messageId;
            Console.WriteLine("messageId:{0}", messageId);
            var taskCompletionSource = new SyncContextTaskCompletionSource<DevToolsMethodResponse>();

            taskCompletionSource.SyncContext = CaptureSyncContext ? SynchronizationContext.Current : syncContext;

            if (!queuedCommandResults.TryAdd(messageId, taskCompletionSource))
            {
                throw new DevToolsClientException(string.Format("Unable to add MessageId {0} to queuedCommandResults ConcurrentDictionary.", messageId));
            }

            var browserHost = browser.GetHost();

            //Currently on CEF UI Thread we can directly execute
            if (CefThread.CurrentlyOnUiThread)
            {
                Console.WriteLine("Currently on CEF UI Thread");
                var returnedMessageId = browserHost.ExecuteDevToolsMethod(messageId, method, parameters);
                if (returnedMessageId == 0)
                {
                    return new DevToolsMethodResponse { Success = false };
                }
                else if(returnedMessageId != messageId)
                {
                    //For some reason our message Id's don't match
                    throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", returnedMessageId, messageId));
                }
            }
            //ExecuteDevToolsMethod can only be called on the CEF UI Thread
            else if (CefThread.CanExecuteOnUiThread)
            {
                Console.WriteLine("ExecuteDevToolsMethod can only be called on the CEF UI Thread");
                var returnedMessageId = await CefThread.ExecuteOnUiThread(() =>
                {
                    return browserHost.ExecuteDevToolsMethod(messageId, method, parameters);
                }).ConfigureAwait(false);

                if (returnedMessageId == 0)
                {
                    return new DevToolsMethodResponse { Success = false };
                }
                else if (returnedMessageId != messageId)
                {
                    //For some reason our message Id's don't match
                    throw new DevToolsClientException(string.Format("Generated MessageId {0} doesn't match returned Message Id {1}", returnedMessageId, messageId));
                }
            }
            else
            {
                throw new DevToolsClientException("Unable to invoke ExecuteDevToolsMethod on CEF UI Thread.");
            }

            return await taskCompletionSource.Task;
        }

 

输出lastMessageId,发现每次调用都会被重置回100000,而直接调用ExecuteDevToolsMethod,每次returnedMessageId都用+1,看了一个CEF源码,nextid会自加1,发现DevToolsExtensions中的方法每次都会重置了,browser.GetDevToolsClient()每次都会重置,于是直接把pageClient先保存起来,不再每次去GetDevToolsClient,成功截图

CefSharp.DevTools.Page.PageClient pageClien= null;
        private async void Test2()
        {
           if(pageClien==null)
            {
                pageClien =  webBrowser.GetBrowser().GetDevToolsClient().Page;
            }

            var result = await pageClien.CaptureScreenshotAsync();
            
            if (result.Data!=null)
            {

                MemoryStream ms = new MemoryStream(result.Data);
                ms.Write(result.Data, 0, result.Data.Length);
                pictureBox1.Image = Image.FromStream(ms);
                //File.WriteAllBytes("1.bmp", result.Data);保存图片
            }
            
        }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: CefSharp是一个.NET包装器,它提供了对Chromium浏览器的访问。要调用javascript获取返回值,可以使用CefSharp的ExecuteScriptAsync()方法。该方法以脚本字符串作为参数,并返回Task类型的结果。这意味着您可以异步调用javascript函数,并在调用成功后获取返回值。 在执行javascript代码后,您将获取一个JavascriptResponse对象,其中包含执行结果的字符串值和一个布尔值,指示脚本是否成功在浏览器中运行。如果脚本未成功执行,则会提供一个错误消息。 以下是一个简单的示例,它演示了如何使用CefSharp执行一个简单的javascript函数并获取返回值: ```csharp var task = browserControl.ExecuteScriptAsync("document.title"); task.ContinueWith(t => { if (!t.IsFaulted) { var response = t.Result; if (response.Success && response.Result != null) { //获取返回值 var result = response.Result.ToString(); MessageBox.Show(result); } else if (!response.Success) { //输出错误消息 MessageBox.Show(response.Message); } } }, TaskScheduler.FromCurrentSynchronizationContext()); ``` 在这个示例中,我们使用ExecuteScriptAsync()方法执行了一个简单的javascript代码(获取页面的标题),并使用ContinueWith()方法处理返回值。在ContinueWith()方法中,我们检查返回的JavascriptResponse对象是否包含成功的结果,如果是,我们将结果存储在result变量中并显示在一个消息框中。 总之,CefSharp可以让我们方便的访问Chromium浏览器的功能,包括执行javascript代码并获取返回值。通过使用.ExecuteScriptAsync()方法,我们可以异步执行javascript代码,并在获取结果后轻松处理返回的JavascriptResponse对象。 ### 回答2: cefsharp是一款基于Chromium开源浏览器的.NET框架,它提供了一种方便的方式来嵌入浏览器引擎到你的应用程序中。如果想要使用cefsharp调用JS获取返回值,首先需要在.NET平台上使用C#编写代码。 我们可以通过cefsharp提供的接口获取浏览器引擎对象,然后通过该对象调用浏览器引擎中的JavaScript接口。最简单的方式是使用CEFSharp.DevTools,它提供了一系列的方法来处理JavaScript代码并返回结果。例如: ```csharp using CefSharp; using CefSharp.DevTools; using CefSharp.DevTools.DOM; var browser = new ChromiumWebBrowser("http://www.google.com"); //等待浏览器加载完成 browser.FrameLoadEnd += (sender, e) => { if (e.Frame.IsMain) { browser.ExecuteScriptAsync("document.body.style.zoom = \"200%\";"); var dom = browser.GetMainFrame().GetDevToolsSession(); var result = dom.EvaluateScriptAsync("document.title"); //通过Task异步等待返回结果 result.ContinueWith(task => { Console.WriteLine(result.Result.Result.Value); }, TaskContinuationOptions.OnlyOnRanToCompletion); } }; ``` 上述代码中,通过CreateDevToolsSessionAsync方法获取到DevToolsSession对象(即浏览器页面的DOM),然后通过EvaluateScriptAsync方法执行JS代码,最后通过ContinueWith方法等待返回结果。在这个例子中,我们通过执行document.title代码,读取了当前页面的标题信息。 需要注意的是,CEFSharp.DevTools仅在Chrome 63或以上版本中提供支持。如果您要运行旧版本的Chrome,请参考CEFSharp.CefSharpExtensions来实现类似的JavaScript代码处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值