Стандартный способ встроить расширение Chrome в Chromium - PullRequest
0 голосов
/ 02 мая 2018

Я создал расширение Chrome, которое я устанавливал в Chrome с помощью Selenium.

Теперь я хотел бы собрать свой собственный Chromium из исходного кода, чтобы мое расширение было предварительно встроено в встроенный распределенный пакет, чтобы мне не приходилось беспокоиться о необходимости Selenium для установки файла CRX для моего варианта использования.

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

Я нашел несколько советов о том, как системный администратор может принудительно установить расширения в Chromium для пользователей в их сети: https://support.google.com/chrome/a/answer/6306504?hl=en Но это для Chrome Enterprise, вероятно, не будет полезным для меня.

Вот еще один пост, в котором рассказывается о том, как автономно устанавливать расширения Chrome . Я мог бы использовать это, чтобы добиться желаемого.

Кто-нибудь имел успех на самом деле встраивание в хром CRX, так что CRX просто устанавливается автоматически?

Быстрое обновление:

Хочу только отметить: я устанавливаю свою пользовательскую версию Chrome с помощью установщика InnoSetup. Поэтому у меня есть возможность после установки моей хром-форка выполнить некоторые пользовательские шаги выполнения после установки. А мои расширения размещены в интернет-магазине Chrome и одобрены.

Так что, если есть какой-то способ программно установить расширения Chrome в установку Chromium из интернет-магазина, я мог бы легко это использовать.

1 Ответ

0 голосов
/ 12 мая 2018

Это было протестировано в нашей версии 66.0.3359.139 Chromium для Windows 10. Процесс связывания расширений может отличаться для Linux и OS X. Я также попытался максимально упростить выполнение этой задачи. Есть несколько вещей, которые вы должны будете сделать, чтобы выполнить это:

  1. Добавьте ваш файл расширений Chromium (.crx) в список расширений по умолчанию для комплектации с мини-установщиком
  2. Узнайте идентификатор этого расширения
  3. Автоматизировать процесс установки плагина
  4. Обход чека в Интернет-магазине Chrome
  5. Сборка мини-инсталлятора для установки вилки Chromium

1: Чтобы связать ваше расширение с установщиком, вам необходимо изменить: src\chrome\browser\extensions\default_extensions\BUILD.gn файл. Предположим, что tab_capture.crx является вашим расширением, тогда его содержимое должно выглядеть примерно так:

if (is_win) {
copy("default_extensions") {
sources = [
  "external_extensions.json",
  "tab_capture.crx"
]
outputs = [
  "$root_out_dir/extensions/{{source_file_part}}",
]

Я только что добавил tab_capture.crx и больше ничего не модифицировал. Ваш файл расширения должен быть в этом месте: src\chrome\browser\extensions\default_extensions\tab_capture.crx

2: Каждому добавочному номеру будет присвоен уникальный идентификатор, назначенный ему Chromium для идентификации этого добавочного номера. Чтобы узнать идентификатор вашего расширения, вам нужно перейти на страницу chrome://extensions/ и перетащить файл crx. Диалоговое окно подтверждения должно появиться. Нажмите кнопку Add extension и убедитесь, что Developer mode включен, тогда ваш идентификатор должен быть виден, но расширение будет отключено, как показано ниже:

enter image description here

3: Теперь мы начнем изменять исходные файлы C ++. Давайте объявим имя и идентификатор нашего расширения. Мы сделаем это в следующих файлах: src\extensions\common\extension.h

namespace extensions {

extern const int kOurNumExtensions;
extern const char* kOurExtensionIds[];
extern const char* kOurExtensionFilenames[];

Я только что объявил эти переменные ниже extensions пространства имен. Помните, что идентификатор добавочного номера, который мы назначаем ниже, должен совпадать с идентификатором добавочного номера, назначенным Chromium.

Определение этих переменных в: src\extensions\common\extension.cc

namespace extensions {

const char* kOurExtensionIds[] = {
    "aaaaaaaaaaaaaaaaaaaaaaaaaaa"}; // Assumed extension ID of tab_capture
const char* kOurExtensionFilenames[] = {
    "tab_capture.crx"};
const int kOurNumExtensions = 1;

Chromium создаст профиль при первом запуске. Поэтому мы предполагаем, что профиль еще не существует, потому что мы установим наше расширение во время выполнения, когда оно будет запущено впервые. Профиль на компьютере с Windows обычно должен существовать здесь: C:\Users\Username\AppData\Local\CompanyName\ChromiumForkName, поэтому обязательно удалите папку CompanyName перед запуском Chromium. Конечно, мы можем выполнить процесс установки и после создания профиля. Для этого вам нужно проверить, установлено ли наше расширение или нет, чтобы предотвратить несколько попыток установки.

Chromium обрабатывает материалы для запуска запуска браузера в этом файле: src\chrome\browser\ui\startup\startup_browser_creator.cc, поэтому мы устанавливаем этот плагин после инициализации профиля и запуска браузера. Вам также нужно будет добавить несколько заголовочных файлов. Мы сделаем это в LaunchBrowser методе:

// Add these header files cause we we will be using them
#include "base/path_service.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/chrome_paths.h"
#include "extensions/browser/extension_system.h"

bool StartupBrowserCreator::LaunchBrowser(
const base::CommandLine& command_line,
Profile* profile,
const base::FilePath& cur_dir,
chrome::startup::IsProcessStartup process_startup,
chrome::startup::IsFirstRun is_first_run) {
    // Omitted Chromium code
    in_synchronous_profile_launch_ = false;
}

// Install our extension
base::FilePath extension_dir;
if (first_run::IsChromeFirstRun() &&
    base::PathService::Get(chrome::DIR_EXTERNAL_EXTENSIONS, &extension_dir)) 
{
    for (int i = 0; i < extensions::kOurNumExtensions; ++i) {
        base::FilePath file_to_install(extension_dir.AppendASCII(
            extensions::kOurExtensionFilenames[i]));
        std::unique_ptr<ExtensionInstallPrompt> prompt(
            new ExtensionInstallPrompt(chrome::FindBrowserWithProfile(profile)->tab_strip_model()->GetActiveWebContents()));
        scoped_refptr<extensions::CrxInstaller> crx_installer(extensions::CrxInstaller::Create(
            extensions::ExtensionSystem::Get(profile)->extension_service(), std::move(prompt)));
        crx_installer->set_error_on_unsupported_requirements(true);
        crx_installer->set_off_store_install_allow_reason(
            extensions::CrxInstaller::OffStoreInstallAllowedFromSettingsPage);
        crx_installer->set_install_immediately(true);
        crx_installer->InstallCrx(file_to_install);
    }
}
// End of install our extension

// Chromium code
profile_launch_observer.Get().AddLaunched(profile);

Это должно установить наше расширение, но так как мы хотим, чтобы наше расширение было принудительно установлено без какого-либо взаимодействия с пользователем, давайте сделаем это здесь: chrome/browser/extensions/extension_install_prompt.cc

void ExtensionInstallPrompt::ShowDialog(
const DoneCallback& done_callback,
const Extension* extension,
const SkBitmap* icon,
std::unique_ptr<Prompt> prompt,
std::unique_ptr<const PermissionSet> custom_permissions,
const ShowDialogCallback& show_dialog_callback) {
// Chromium code
return;
}

// Don't show add extension prompt for our extensions
for (int i = 0; i < extensions::kOurNumExtensions; ++i) {
    if (extension->id() == extensions::kOurExtensionIds[i]) {
        base::ResetAndReturn(&done_callback_).Run(Result::ACCEPTED);
        return;
    }
}
// End of don't show add extension prompt for our extensions

// Chromium code
LoadImageIfNeeded();

4: Даже если мы автоматизируем процесс установки, Chromium отключит наше расширение, так как оно не было установлено из Chrome Web Store. Это обрабатывается здесь: src\chrome\browser\extensions\install_verifier.cc в этом методе:

bool InstallVerifier::MustRemainDisabled(const Extension* extension,
                                     disable_reason::DisableReason* reason,
                                     base::string16* error) const {
// Omitted Chromium code

// Chromium code
if (Manifest::IsUnpackedLocation(extension->location())) {
MustRemainDisabledHistogram(UNPACKED);
return false;
}

// Always enable our tab capture extension
// Use loop if you have more than one extension
if (extension->id() == extensions::kOurExtensionIds[0]) {
    return false;
}
// End of always enable our tab capture extension

// Chromium code
if (extension->location() == Manifest::COMPONENT) {
    MustRemainDisabledHistogram(COMPONENT);
    return false;
}

Это гарантирует, что наше расширение будет включено, поскольку мы обходим проверку Chrome Web Store.

Если вы не хотите, чтобы ваше расширение удалялось и оставалось включенным, вы можете сделать это, изменив этот файл: chrome/browser/extensions/standard_management_policy_provider.cc и изменив следующие методы: MustRemainInstalled и MustRemainEnabled

5: Теперь вы можете собрать мини-установщик, выполнив эту команду ninja -C out\BuildFolder mini_installer для сборки mini_installer.exe. Если вы передадите аргумент --system-level в mini_installer.exe, тогда он должен установить вашу вилку Chromium в папку Program files. После завершения установки ваш файл crx должен находиться здесь: C:\Program Files (x86)\YourChromium\Application\66.0.3359.139\Extensions\tab_capture.crx.

Chromium распакует и установит этот crx-файл в ваш профиль: C:\Users\Username\AppData\Local\YourChromium\User Data\Default\Extensions (Предполагаемый профиль по умолчанию)

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

Дайте мне знать, если это работает. Это заняло больше времени, чем ожидалось, потому что я заметил много изменений в их кодовой базе, и наш старый код не работал в этой последней сборке Chromium. Уверен, больше ничего не пропустил:)

...