List icon Contents

Chrome Extensions

This page describes how to work with Chrome extensions.

The functionality described in this article is availabble in DotNetBrowser 3.0.0-eap.2 or higher.

DotNetBrowser provides the Extensions API that allows you to install, update, and uninstall Chrome extensions. The extensions work on a per-profile basis and are not shared with other profiles. To access the extensions of a specific profile, use the following approach:

IExtensions extensions = profile.Extensions();

If you delete the profile, all installed extensions for this profile will be deleted as well.

Installing extensions

You can install Chrome extensions manually from Chrome Web Store or programmatically from CRX files.

We recommend that you install extensions from CRX files if you trust the source of the extension. Comparing to installing extensions from Chrome Web Store, it gives you the following benefits:

  1. You control the version of the extension that you install. You can test the extension with a specific DotNetBrowser version and make sure that it works as expected with the Chromium build that DotNetBrowser uses. If you install the extension from Chrome Web Store, you install the latest version of the extension that may not be compatible with the DotNetBrowser version you use.
  2. You can deploy the extension with your application and install it automatically. So, you don’t need to ask users to install the extension manually from Chrome Web Store.
  3. You can install extensions that are not available in Chrome Web Store. If you develop an extension you would like to use in DotNetBrowser and you don’t want to publish it in Chrome Web Store, you can pack it into a CRX file and use it.

To install an extension from a CRX file, use the following approach:

string crxPath = Path.GetFullPath("path/to/extension.crx");
IExtension extension = await extensions.Install(crx);

The method returns an instance of the installed extension. All the required permissions required by the extension are automatically granted.

Important: Be very cautious about the extensions you are installing. In Chrome Web Store, the CRX file must have publisher proof, which is obtained upon extension publishing. In DotNetBrowser, we allow users to install the extensions without publisher proof, so be cautious about the resources you use to obtain CRX files.

Installing extensions from Chrome Web Store is disabled by default for security reasons. If you want to let users install extensions from Chrome Web Store, you need to allow installation using the following approach:

extensions.InstallExtensionHandler =
    new Handler<InstallExtensionParameters, InstallExtensionResponse>(p => 
        InstallExtensionResponse.Install);

Every time the user clicks the “Add to Chrome” button on the Chrome Web Store page, the InstallExtensionHandler will be invoked. You can get info about the extension that the user wants to install from the InstallExtensionParameters object and decide whether to allow the installation or not:

extensions.InstallExtensionHandler =
    new Handler<InstallExtensionParameters, InstallExtensionResponse>(p => 
    {
        string name = p.ExtensionName;
        string version = p.ExtensionVersion;
        if (name.Equals("uBlock Origin") && version.Equals("1.35.2")) 
        {
            return InstallExtensionResponse.Install;
        } 
        else 
        {
            return InstallExtensionResponse.Cancel;
        }
    });

To get notified when the extension is installed, use the ExtensionInstalled event:

extensions.ExtensionInstalled += (s, e) => 
{
    IExtension installedExtension = e.Extension;
});

Updating extensions

If you install an extension from a CRX file, and you would like to update it with a new version, you just need to install it from a new CRX file:

string updatedCrxPath = Path.GetFullPath("path/to/updated_extension.crx");
IExtension extension = await extensions.Install(updatedCrxPath);

You don’t need to delete the previous version of the extension. DotNetBrowser will automatically update the extension to the newest version.

Important: When you are installing an extension without publisher proof, be sure to use the same private key (.pem file) for packaging. When a different private key is used or not used at all, the extension would be considered as new and would be installed again without updating.

If you install an extension from Chrome Web Store, you can’t update it programmatically. The user should update the extension manually from the extension page in Chrome Web Store.

To get notified when the extension is updated, use the ExtensionUpdated event:

extensions.ExtensionUpdated += (s, e) => 
{
    IExtension updatedExtension = e.Extension;
});

Uninstalling extensions

You can programmatically uninstall the extension you installed from a CRX file or Chrome Web Store:

IExtension extension = 
    extensions.All.FirstOrDefault(ex => ex.Name.Equals("uBlock Origin"));
await extension.Uninstall();

If the extension was installed manually from Chrome Web Store, the user might want to uninstall it manually as well. By default, uninstalling extensions from Chrome Web Store is disabled for security reasons. If you want to allow users to uninstall extensions from Chrome Web Store or the chrome://extensions page, you need to allow uninstallation:

extensions.UninstallExtensionHandler =
    new Handler<UninstallExtensionParameters, UninstallExtensionResponse>(p => 
        UninstallExtensionResponse.Uninstall);

To get notified when the extension is uninstalled, use the ExtensionUninstalled event:

extensions.ExtensionUninstalled += (s, e) => 
{
    string extensionId = e.ExtensionId;
});

An attempt to work with an uninstalled extension will result in an ObjectDisposedException.

Extension action

Chrome extensions may provide features that are available only in the “extension action popup”. This is a dialog that you see when clicking on the extension icon in the Chrome toolbar. Even though DotNetBrowser does not display Chrome toolbar. Instead, it provides an API for interacting with the extension action popup.

To simulate the click on the extension icon (extension action) in Chrome toolbar for a specific tab, execute the following code:

extension.GetAction(browser)?.Click();

An extension, not Chromium, is responsible for picking a browser to interact with. Therefore, the extension action may not be executed for the browser it was obtained for.

If you want to display the extension icon in your application, you can access the extension action properties and subscribe to the action update notifications:

IExtensionAction action = extension.GetAction(browser);

if (action != null) 
{
    // Get the properties of the action.
    Bitmap icon = action.Icon;
    string badge = action.Badge;
    string tooltip = action.Tooltip;
    bool enabled = action.IsEnabled;

    // Get notifications when the extension action is updated.
    action.Updated += (s, e) => 
    {
        IExtensionAction updatedAction = e.ExtensionAction;
    });
});

Extension action popups

When you create a BrowserView instance, it will register the default implementations of the OpenExtensionActionPopupHandler callback that will display the extension action popup when the program simulates the click on the extension action icon.

If you want to display a custom extension action popup, register your own implementation of the OpenExtensionActionPopupHandler:

Browser.OpenExtensionActionPopupHandler = 
    new Handler<OpenExtensionActionPopupParameters>(p =>
    {
        IBrowser popupBrowser = p.PopupBrowser;
    });

Extension popups

Some extensions may want to open popup windows to show a website or some other content. By default, DotNetBrowser blocks such popups. To allow the extension to show popups, register your own implementation of the following callbacks:

extension.OpenExtensionPopupHandler = 
    new Handler<OpenExtensionPopupParameters>(p =>
    {
        IBrowser popupBrowser = p.PopupBrowser;
    });

Or use the default implementation:

extension.OpenExtensionPopupHandler = new DefaultOpenExtensionPopupHandler(browserView);

Please note that “extension popups” and “extension action popups” are different things.

Peculiarities & limitations

We designed extension API with the goal to behave as Chromium as much as possible. But since DotNetBrowser is an embedded browser, we can’t ensure the same behavior for every case. Thus, there are peculiarities and limitations that you should have in mind when working with extensions.

  1. All tabs are opened as new windows.
  2. chrome.tabs.query never takes into account extension action popups.
  3. Windows of the extension action popup are auto-resizable. The size is regulated by the extension action.
  4. When DotNetBrowser does not find the manifest for native messaging (chrome.runtime.connectNative) in the user data directory or Chromium application data, it checks it in Chrome application data.

There are certain limitations related to Chromium tabs, windows, and other UI elements. The windows.Window is mapped to a native window associated with the browser, not the .NET window it is embedded into (if any). Thus, methods and properties of the windows.Window object, such as Window.width, Window.height, Window.focused, etc., are bound to that native window.

Unsupported extensions APIs

Below is the list of Chromium Extension APIs that are not supported in DotNetBrowser:

  • chrome.tabs.discard
  • chrome.tabs.remove
  • chrome.tabs.duplicate
  • chrome.windows.remove
  • chrome.windows.update
  • chrome.window.create with more than one URL in parameters
  • chrome.sessions.restore
  • chrome.desktopCapture.chooseDesktopMedia.

If an extension calls an unsupported method that returns a Promise, it will be rejected with an error. If a method accepts a callback, the chrome.runtime.lastError property will be set to an error.

Downloading CRX from Chrome Web Store

If you want to download a CRX file of an extension available in Chrome Web Store, then you can register the InstallExtensionCallback callback where you can get an absolute path to the CRX file of the extension that is about to be installed from Chrome Web Store and make a copy of it to a different location:

extensions.InstallExtensionHandler =
    new Handler<InstallExtensionParameters, InstallExtensionResponse>(p =>
    { 
        string name = p.ExtensionName;
        string version = p.ExtensionVersion;
        string sourceCrxFilePath = Path.GetFullPath(p.ExtensionCrxFile);
        string targetCrxFilePath = Path.GetFullPath(name + "-" + version + ".crx");
        try {
            File.Copy(sourceCrxFilePath, targetCrxFilePath);
        } catch (IOException e) {
            throw new InvalidOperationException(e);
        }
        return InstallExtensionResponse.Cancel;
    });

Now, you can load the required extension in Chrome Web Store and click the “Add to Chrome” button. The callback will be invoked, and the CRX file of the extension will be copied to the specified location.

Go Top