Как убить подпроцесс встроенной инфраструктуры хрома?

в компьютерной игре у меня есть браузер, используемый для новостей, магазина виртуальной валюты и социальных сетей. Он был построен с совершенно новым обновлением Chromium Embedded Framework. Проблема заключается в том, когда я открываю окно браузера (там работает сайт там хорошо), а затем закрывается, для некоторых сайтов подпроцесс CEF не заканчивается. Я также могу продолжить прослушивание звука, например, если это видео Youtube. Я использую offscreen рендеринг, другие родные окна не создаются, а только подпроцессы. Чтобы закрыть окно браузера, я удаляю все ссылки на CefBrowser и вызываю:

m_browser->GetHost()->CloseBrowser(true);

Я также пробовал другие способы закрыть/уничтожить/финализировать этот подпроцесс рендеринга, например, загружать "about: blank" перед закрытием, но это не помогло: процесс не спал, звук продолжал играть. Важное замечание: это происходит только на некоторых веб-сайтах, которые, я полагаю, используют какую-то особенность, а другие нет. Когда я пытался отключить JavaScript в настройках CEF, ошибка исчезла, но мне нужна JS.

  • Есть ли способ заставить подпроцесс kill kill? (Обратите внимание, что GetWindowHandle возвращает 0, потому что у него нет окна)
  • Есть ли другой способ правильно закрыть браузер, который я не знаю?
  • Какая особенность веб-сайтов может вызвать такую ​​ошибку?

Спасибо!

Конфигурация времени CEF: многопроцессорный, однопоточный цикл сообщений, с подпроцессом, без окон, без песочницы.

Конфигурация ПК: ОС Windows 8, VS 2010, Chromium Embedded Framework версии 3.3071, сборка 1649, язык С++.

Ответ 1

Вы должны проверить свою реализацию onbeforeunload.

CEF GeneralUsage пишет о CefBrowserHost:: CloseBrowser: Затем родительскому окну нужно вызвать CloseBrowser (ложь) и дождаться второго события закрытия ОС, чтобы указать, что браузер разрешил закрытие. Второе событие закрытия ОС не будет отправлено, если закрытие отменено JavaScript-обработчиком события onbeforeunload или обратным вызовом DoClose().

И если вы все еще хотите просто убить подпроцесс, я бы предложил вам использовать сообщение IPC браузера и выйти из приложения. При запуске игры

CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create(KILL_subprocess);
m_browser->SendProcessMessage(PID_RENDERER, msg);

а в подпроцессе реализуется "OnProcessMessageReceived":

if (msg->GetName() == KILL_subprocess)
{
    delete this;
    std::exit(EXIT_FAILURE);
}

Ответ 2

При создании потока для отслеживания выхода родительского процесса и закрытия подпроцесса установите статическое свойство "CefSharp.CefSharpSettings.SubprocessExitIfParentProcessClosed = true;" перед вызовом Cef.Initialize.

Ответ 3

foreach (var process in Process.GetProcessesByName("CefSharp.BrowserSubprocess"))
{
    process.Kill()
}