Приложение CEF4Delphi не может запускать два экземпляра

У меня есть приложение Delphi со встроенным браузером CEF, и оно перестало работать с тех пор, как я обновил CEF 117.1.4 и Chromium 117.0.5938.92 до CEF 123.0.12 и Chromium 123.0.6312.107.

С CEF 117 я могу без проблем запустить два экземпляра приложения, но теперь при запуске второго экземпляра происходит сбой:

begin
  GlobalCEFApp := TCefApplication.Create;

  InicializaCef;

  // Reducir el número de locales a un mínimo
  GlobalCEFApp.LocalesRequired := 'ca,de,en-GB,en-US,es-419,es,fr,it,pt-BR,pt-PT';
  GlobalCEFApp.SetCurrentDir := True;
  GlobalCEFApp.LocalesDirPath := 'locales';

  Application.Initialize;
  Application.Title := 'QBrowser';
  Application.CreateForm(TMainForm, MainForm);
  test := GlobalCEFApp.StartMainProcess;
  if test then
    Application.Run;

  GlobalCEFApp.Free;
  GlobalCEFApp := nil;
end.

GlobalCEFApp.StartMainProcess теперь возвращает False.

Есть ли какое-то новое значение конфигурации, которое я упускаю из виду?

Почему бы не спросить его автора?

AmigoJack 21.06.2024 14:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
1
220
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

CEF изменил способ инициализации и теперь проверяет, работает ли другое приложение с той же настройкой RootCache. Эта функция была добавлена ​​в CEF 120.1.8.

Если GlobalCEFApp.Cache и GlobalCEFApp.RootCache пусты, то будет использоваться каталог конкретной платформы по умолчанию. В случае с Windows: %AppData%\Local\CEF\User Data\.

Использование каталога по умолчанию не рекомендуется в производственных приложениях. Запись нескольких экземпляров приложения в один и тот же каталог GlobalCEFApp.RootCache может привести к повреждению данных.

Есть два способа избежать этого:

  1. Внедрите GlobalCEFApp.OnAlreadyRunningAppRelaunch, чтобы получать уведомления о запуске нового экземпляра приложения и открытии новой вкладки или дочерней формы в веб-браузере.
  2. Используйте отдельный каталог GlobalCEFApp.RootCache для каждого экземпляра приложения.

Прочтите документацию, чтобы узнать все подробности (найдите TCefApplicationCore по типу) о:

  • GlobalCEFApp.OnAlreadyRunningAppRelaunch:

    Реализуйте эту функцию, чтобы обеспечить поведение, специфичное для приложения, когда уже запущенное приложение перезапускается с тем же значением TCefSettings.root_cache_path. Например, активируйте существующее окно приложения или создайте новое окно приложения. command_line будет доступен только для чтения. Не оставляйте ссылку на command_line вне этой функции. Верните true (1), если перезапуск обработан, или false (0) для поведения перезапуска по умолчанию. Поведение по умолчанию создаст новое окно Chrome в стиле по умолчанию.

    Чтобы избежать повреждения кэша, для данного значения TCefSettings.root_cache_path разрешен запуск только одного экземпляра приложения. При перезапуске приложение проверяет одноэлементную блокировку процесса, а затем пересылает новые аргументы запуска уже запущенному процессу приложения перед досрочным завершением. Поэтому клиентские приложения должны проверить возвращаемое значение cef_initialize() для раннего выхода, прежде чем продолжить.

    Эта функция будет вызываться в потоке пользовательского интерфейса процесса браузера.

  • GlobalCEFApp.RootCache:

    Корневой каталог для данных, относящихся к установке, и родительский каталог для данных, относящихся к профилю. Все значения TCefSettings.cache_path и ICefRequestContextSettings.cache_path должны иметь общий родительский каталог. Если это значение пусто и TCefSettings.cache_path не пусто, то по умолчанию будет установлено значение TCefSettings.cache_path. Любое непустое значение должно быть абсолютным путем. Если оба значения пусты, то будет использоваться каталог по умолчанию, специфичный для платформы (каталог ~/.config/cef_user_data в Linux, каталог ~/Library/Application Support/CEF/User Data в MacOS, каталог AppData\Local\CEF\User Data в каталоге профиля пользователя в Windows). Использование каталога по умолчанию не рекомендуется в производственных приложениях (см. ниже).

    Запись нескольких экземпляров приложения в один и тот же каталог root_cache_path может привести к повреждению данных. Поэтому для защиты от этого используется одноэлементная блокировка процесса на основе значения root_cache_path. Такое одноэлементное поведение применяется ко всем приложениям на основе CEF, использующим версию 120 или новее. Вам следует настроить root_cache_path для своего приложения и реализовать ICefBrowserProcessHandler.OnAlreadyRunningAppRelaunch, который затем будет вызываться при любом перезапуске приложения с тем же значением root_cache_path.

    Неправильная установка значения root_cache_path может привести к сбоям при запуске или другим неожиданным последствиям (например, песочница блокирует доступ для чтения и записи к определенным файлам).

  • GlobalCEFApp.Cache:

    Каталог, в котором на диске будут храниться данные глобального кэша браузера. Если это значение не пусто, то это должен быть абсолютный путь, равный или дочерний каталог TCefSettings.root_cache_path. Если это значение пустое, браузеры будут созданы в «режиме инкогнито», где для хранения используются кэши в памяти, и никакие данные, специфичные для профиля, не сохраняются на диске (данные, специфичные для установки, все равно будут сохраняться в root_cache_path). Базы данных HTML5, такие как localStorage, будут сохраняться между сеансами только в том случае, если указан путь к кэшу. Может быть переопределено для отдельных экземпляров ICefRequestContext с помощью значения ICefRequestContextSettings.cache_path. При использовании среды выполнения Chrome любое значение дочернего каталога будет игнорироваться и вместо него будет использоваться профиль «по умолчанию» (также дочерний каталог).

В документах написано «функция», но TOnAlreadyRunningAppRelaunchEvent — это процедура. Доступ к папке Windows AppData текущего пользователя можно получить с помощью переменной среды %AppData% (также работает в Проводнике).

AmigoJack 21.06.2024 16:43

@salvador-díaz-fau Я следовал вашим инструкциям и теперь успешно запускаю несколько экземпляров. При запуске я создаю случайное имя для папки, которая будет использоваться в качестве кеша: if CreateDir(UniqueCache) then GlobalCEFApp.RootCache := UniqueCache; Но, поскольку я тоже использую GlobalCEFApp.SingleProcess := False, это заканчивается созданием нескольких папок. Есть ли способ создать только один временный кеш? Где мне удалить папку кэша?

Héctor C. 24.06.2024 15:27

Вы можете создавать уникальные каталоги кэша, объединяя идентификатор процесса. Например, «c:\rootcache» + inttostr(MyCurrentProcessID). Затем вы можете периодически удалять неиспользуемые каталоги кэша.

Salvador Díaz Fau 24.06.2024 19:02

Где мне следует удалить временный кеш? Приложение создает несколько папок, но я могу удалить только одну из них. Я попробовал GlobalCEFApp.OnBrowserDestroyed, но он не вызывается.

Héctor C. 25.06.2024 10:55

Если все экземпляры вашего приложения создают каталоги корневого кэша с идентификатором процесса, вы можете получить список всех идентификаторов процессов вашего приложения и сравнить эти значения с именами каталогов корневого кэша. Если каталог корневого кэша имеет неиспользуемый идентификатор процесса, вы можете безопасно удалить его в любое время и из любого места.

Salvador Díaz Fau 25.06.2024 15:48

Другие вопросы по теме