等待DevTools加载

时间:2019-06-19 14:55:39

标签: c# google-chrome-devtools cefsharp chromium-embedded

如何检测DevTools何时完成加载?

在CefSharp中,您可以使用ShowDevTools()扩展方法打开DevTools窗口。我想指示嵌入式浏览器仅在DevTools加载后(特别是在附加了JavaScript调试器之后)加载页面。但是,ShowDevTools()似乎是异步执行的。

1 个答案:

答案 0 :(得分:0)

一些错误的开始之后,下面显示的我的ShowDevToolsAsync扩展方法似乎工作可靠。

请注意,我正在使用https://stackoverflow.com/a/7809413/3063273的修改来检测DevTools何时完成加载。我不确定会有什么更可靠的选择。也许您可以像对OP的建议一样插入ILoadHandler.OnFrameLoadEnd并从那里开始工作。我尝试了这条路径,但是在我找到更直接,更明显的解决方案之前,还没有走太远。

重要:您的ChromiumWebBrowser实例必须已经加载了一个网页(或至少已开始加载一个网页),否则DevTools将永远不会进入该网页,但会只是坐在那里,收到以下消息:

DevTools was disconnected from the page

如果您要确保DevTools在加载页面之前已启动(例如,以确保其Javascript调试器已准备就绪,甚至可以捕获最早的错误),请让ChromiumWebBrowser加载一个虚拟页面,例如{ {1}},然后等待DevTools出现,然后加载页面。

<html>Loading DevTools...</html>

用法示例(使用上面未显示的其他扩展方法,但您应该了解要点)

using System;
using System.Threading;
using System.Threading.Tasks;
using CefSharp;
using CefSharp.WinForms;

public static class ChromiumWebBrowserExtensions
{
    public static async Task ShowDevToolsAsync(
        this ChromiumWebBrowser browser,
        CancellationToken cancellationToken)
    {
        browser.ShowDevTools();

        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Detect if console is open
            var result = await browser.EvaluateScriptAsync(@"
(function(){
    // Inspired by https://stackoverflow.com/a/7809413/3063273
    var detector = function(){};
    detector.isOpened = false;
    detector.toString = function(){
        this.isOpened = true;
    };
    console.log('%c', detector);
    return detector.isOpened;
})()
", timeout: TimeSpan.FromSeconds(1));
            if (!result.Success)
            {
                throw new Exception(result.Message);
            }
            if (!(result.Result is bool isOpened))
                continue;
            if (isOpened)
                break;
            await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
        }
    }
}

编辑:添加了异步延迟以减少public async Task DemonstrateAsync(ChromiumWebBrowser browser, CancellationToken cancellationToken) { // Give DevTools something to hook into await browser.LoadDataUrlAsync("<html>Waiting for DevTools to load...</html>", cancellationToken); // Show DevTools and wait until it's up await browser.ShowDevToolsAsync(cancellationToken); // Give the Javascript debugger a breakpoint await browser.LoadDataUrlAsync("<html><script>debugger;</script></html>", cancellationToken); } 循环的迭代次数。 100ms是一个任意数字,对我来说,迭代次数从> 300减少到了〜3。