Событие или уведомление о выходе или сбое подпроцесса cefsharp - PullRequest
0 голосов
/ 11 июня 2018

Есть клиент WPF, использующий последний пакет CefSharp для размещения веб-приложений.Поскольку у нас есть несколько веб-приложений, у нас есть несколько представлений, каждое из которых имеет собственный экземпляр браузера / BrowserSubProcess.

Скажем, из-за отсутствия лучшего примера я просто захожу в диспетчер задач и убиваю один из SubProcess.exe.Есть ли событие, к которому мы можем подключиться или иным образом получить уведомление?

Одной из мыслей было бы подключиться к процессу, выполнив запрос через какой-то пинвоук, но это банка червей, которую я бы предпочел не открывать.

1 Ответ

0 голосов
/ 12 июня 2018

Спасибо @amaitland за то, что он указал мне правильное направление.Это немного иголка в стоге сена, но он есть.

Для всех, кто заинтересован, вы должны реализовать IRequestHandler, на который ссылается его комментарий выше.Вы можете

  1. сделать это с нуля,
  2. использовать их полностью реализованный пример на Пример RequestHandler ,
  3. или сделать что-то среднее между использованием DefaultRequestHandler ( Пример переопределения DefaultRequestHandler ).

Поэтому, если мы используем DefaultRequestHandler, мы можем сделать что-то подобное только для завершенного события:

/// <summary>
/// Handle events related to browser requests.
/// </summary>
public class RequestHandler : DefaultRequestHandler
{
    /// <summary>
    /// Called when the render process terminates unexpectedly.
    /// </summary>
    /// <param name="browserControl">The ChromiumWebBrowser control</param>
    /// <param name="browser">the browser object</param>
    /// <param name="status">indicates how the process terminated.</param>
    /// <remarks>
    /// Remember that <see cref="browserControl"/> is likely on a different thread so care should be used
    /// when accessing its properties.
    /// </remarks>
    public override void OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status)
    {
        switch (status)
        {
            case CefTerminationStatus.AbnormalTermination:
                Log.Error("Browser terminated abnormally.");
                break;

            case CefTerminationStatus.ProcessWasKilled:
                Log.Error("Browser was killed.");
                break;

            case CefTerminationStatus.ProcessCrashed:
                Log.Error("Browser crashed while.");
                break;

            default:
                Log.Error($"Browser terminated with unhandled status '{status}' while at address.");
                break;
        }

        RenderProcessTerminated?.Invoke(browserControl, status);
    }

    /// <summary>
    /// Fires when the render process terminates unexpectedly.
    /// </summary>
    public event EventHandler<CefTerminationStatus> RenderProcessTerminated;
}

Если у нас есть объект браузера, объявленный в представлении, как, скажем,

<!--Bound to the ViewModel.Address property-->
<cef:ChromiumWebBrowser
    x:Name="Browser"
    Address="{Binding Address}">
</cef:ChromiumWebBrowser>

Затем просто подключите новый экземпляр:

private readonly Dispatcher _mainDispatcher;
private readonly RequestHandler _requestHandler = new RequestHandler();

public MainWindow()
{
    InitializeComponent();

    _mainDispatcher = Dispatcher.CurrentDispatcher;
    _requestHandler.RenderProcessTerminated += OnBrowserRenderProcessTerminated;
    Browser.RequestHandler = _requestHandler;
}

private void OnBrowserRenderProcessTerminated(object sender, CefTerminationStatus e)
{
    //Likely coming from a background thread
    _mainDispatcher.InvokeAsync(() =>
        Log.Error($"Browser crashed while at address: {Browser.Address}")
    );
}
...