我已经建立了一个Chrome扩展程序,该扩展程序已使用Selenium安装到Chrome中。
现在,我想从源代码构建自己的Chromium,以便将扩展程序预先捆绑到构建的分布式软件包中,这样我就不必担心需要Selenium为我的用例安装CRX文件。
我发现了几个论坛,有人建议他们尝试一下,但是没有一个看起来像他们成功了。
我发现了一些有关系统管理员如何为其网络中的用户强制将扩展安装到Chrome中的提示:https://support.google.com/chrome/a/answer/6306504?hl=en
但这是针对chrome企业的,可能对我没有用。
Here is another post which talks about how to offline install chrome extensions。我也许可以使用其中的一些来实现我想要的事情。
有人成功将CRX嵌入 Chrome 中,从而可以自动安装CRX吗?
快速更新:
我只想指出:我正在使用InnoSetup安装程序安装chrome的自定义版本。因此,在安装 Chrome 叉后,我确实有机会在安装后执行一些自定义执行步骤。我的扩展程序托管在chrome网站商店中并获得批准。
因此,如果可以通过某种方式从网上商店以编程方式将chrome扩展程序安装到Chromium安装中,则可以轻松地使用它。
最佳答案
这已在Windows 10上的Chromium fork版本66.0.3359.139中进行了测试。对于Linux和OS X,扩展捆绑过程可能有所不同。我还尝试过尽可能轻松地完成此任务。要完成此操作,您需要做几件事:
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,以标识该扩展名。要查找扩展名,请转到
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[];
我刚刚在
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 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网上应用店检查时启用我们的扩展程序。
如果您不希望扩展程序被卸载并保持启用状态,则可以通过修改以下文件来实现:
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 fork安装在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版本中不起作用。我敢肯定,我没有错过任何其他东西:)