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

时间:2018-05-02 01:02:41

标签: c++ google-chrome-extension chromium

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

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

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

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

Here is another post which talks about how to offline install chrome extensions。我或许可以利用其中一些来实现我想要的目标。

有没有人真正成功构建铬一个CRX,以便CRX自动安装?

快速更新:

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

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

1 个答案:

答案 0 :(得分:9)

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

  1. 将您的Chromium扩展程序(.crx)文件添加到默认扩展程序列表中,以便与迷你安装程序捆绑
  2. 找出该扩展程序的ID
  3. 自动化插件安装过程
  4. 通过Chrome网上应用店检查
  5. 构建迷你安装程序以安装Chromium fork
  6. 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分配给它的唯一ID来标识该扩展程序。要查找扩展程序的ID,您应转到chrome://extensions/页面并拖放crx文件。应弹出确认对话框。点击Add extension按钮并确保已启用Developer mode,然后您的ID应该可见,但扩展程序将被停用,如下所示:

    enter image description here

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

    namespace extensions {
    
    extern const int kOurNumExtensions;
    extern const char* kOurExtensionIds[];
    extern const char* kOurExtensionFilenames[];
    

    我刚刚在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;
    

    Chromium会在首次推出时创建个人资料。所以我们假设还没有配置文件,因为我们将在首次启动时在运行时安装我们的扩展。 Windows计算机上的配置文件通常应存在于此处:C:\Users\Username\AppData\Local\CompanyName\ChromiumForkName因此请确保在启动Chromium之前删除CompanyName文件夹。当然,我们也可以在创建配置文件后执行安装过程。为此,您必须检查我们的扩展是否已安装,以防止多次安装尝试。

    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网上应用店安装。它在这里处理: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网上应用店检查。

    如果您不希望卸载并继续启用扩展程序,则可以通过修改此文件来执行此操作:chrome/browser/extensions/standard_management_policy_provider.cc并修改以下方法:MustRemainInstalledMustRemainEnabled

    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(假设默认配置文件)

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

    让我知道它是否有效。花了比预期更长的原因我注意到他们的代码库发生了很多变化,而我们的旧代码在最新的Chromium版本中没有用。我相信,我没有错过任何其他事情:))