将Chrome扩展程序构建到Chromium的标准方法

Nic*_*zza 7 c++ chromium google-chrome-extension

我已经使用Selenium构建了Chrome扩展程序.

现在我想从源代码构建我自己的Chromium,以便我的扩展程序预先捆绑到构建的分布式软件包中,这样我就不必担心需要Selenium为我的用例安装CRX文件.

我找到了几个人们建议他们尝试这个的论坛,但是没有一个论坛看起来像是成功了.

我找到了一些提示,说明系统管理员如何为其网络中的用户强制安装扩展程序:https://support.google.com/chrome/a/answer/6306504?hl = zh-CN 但这可能适用于chrome enterprise,不会对我有用.

这是另一篇文章,讨论如何离线安装chrome扩展.我或许可以使用其中的一些来实现我想要的东西.

有没有人成功实际成为铬 CRX,以便CRX自动安装?

快速更新:

我只想注意:我正在使用InnoSetup安装程序安装我的自定义版Chrome.所以我确实有机会在安装我的铬分叉后,在安装后执行一些自定义执行步骤.我的扩展程序托管在Chrome网上商店并获得批准.

因此,如果有一些方法可以从Web商店以编程方式将Chrome扩展安装到Chromium安装中,我可以轻松地使用它.

Ase*_*esh 9

这已在Windows 10的Chromium fork版本66.0.3359.139中进行了测试.对于Linux和OS X,扩展捆绑过程可能不同.我还尝试尽可能简单地完成此任务.要完成此任务,您需要做几件事:

  1. 将Chromium扩展名(.crx)文件添加到默认扩展名列表中,以便与迷你安装程序捆绑在一起
  2. 找出该扩展的ID
  3. 自动化插件安装过程
  4. 通过Chrome网上应用店检查
  5. 构建迷你安装程序以安装Chromium fork

1:要将扩展程序与安装程序捆绑在一起,您必须修改:src\chrome\browser\extensions\default_extensions\BUILD.gnfile.假设tab_capture.crx是你的扩展,那么它的内容应该是这样的:

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

我刚刚附加tab_capture.crx并没有修改任何其他内容.您的扩展程序文件应位于以下位置:src\chrome\browser\extensions\default_extensions\tab_capture.crx

2:每个分机都有一个由Chromium分配给它的唯一ID,以识别该分机.要查找扩展程序的ID,您应该转到chrome://extensions/页面并拖放crx文件.应弹出确认对话框.单击Add extension按钮并确保Developer mode已启用,然后您的ID应该可见,但扩展名将被禁用,如下所示:

在此输入图像描述

3:现在,我们将开始修改C++源文件.让我们声明我们的扩展名和ID.我们将在这些文件中这样做: src\extensions\common\extension.h

namespace extensions {

extern const int kOurNumExtensions;
extern const char* kOurExtensionIds[];
extern const char* kOurExtensionFilenames[];
Run Code Online (Sandbox Code Playgroud)

我刚刚在extensions命名空间下面声明了这些变量.请注意,我们在下面指定的扩展程序ID必须与Chromium指定的扩展程序ID匹配.

这些变量的定义如下: 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;
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

这应该安装我们的扩展,但是因为我们希望在没有任何用户交互的情况下强制安装我们的扩展,让我们在这里做: 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();
Run Code Online (Sandbox Code Playgroud)

4:即使我们自动化安装过程,Chromium也会禁用我们的扩展程序,因为它未从Chrome网上应用店安装.它在这里处理: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;
}
Run Code Online (Sandbox Code Playgroud)

这将确保我们的扩展程序将启用,因为我们绕过了Chrome网上应用店检查.

如果你不想让你的扩展要卸载并保持启用状态,那么你可以通过修改这个文件这样做:chrome/browser/extensions/standard_management_policy_provider.cc和修改这些方法:MustRemainInstalledMustRemainEnabled

5:现在您可以通过执行此命令ninja -C out\BuildFolder mini_installer来构建迷你安装程序mini_installer.exe.如果你将--system-level参数传递给mini_installer.exe那么它应该在Program files文件夹中安装你的Chromium fork .安装完成后,你的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假设默认配置文件)

注意:为了提高代码可读性和易用性,您可以使用容器类来保存这些扩展文件名及其相应的ID,并在基于for循环的范围内轻松使用它.

如果有效,请告诉我.花了比预期更长的原因我注意到他们的代码库发生了很多变化,而我们的旧代码在最新的Chromium版本中没有用.我相信,我没有错过任何其他:)

  • 我通过将 crx 文件位置包含在 src\chrome\browser\extensions\default_extensions\BUILD.gn 中的组(“default_extension)”中成功地在 Linux 上实现了更改。但是,启动时,我收到一条错误消息“程序包无效” CRX_FILE_NOT_READABLE”显示在启动选项卡页面上,并且未安装扩展。我们可以从该 CRX 手动安装扩展并且运行良好。您能给我关于发生的情况以及如何修复它的任何建议吗 (2认同)
  • 我刚刚弄清楚如何在 Linux 上包含内置扩展。添加复制策略,将 CRX 复制到扩展文件夹下的输出文件。其余的都一样。如果您不想使用迷你安装程序,则只需将 default_extension s 目录包含在您的 extension/build.gn 文件中的公共 deps 中即可。认为这也适用于 MacOS (2认同)