mosheng 发表于 2025-4-10 16:09:41

C#自定义扩展插件事件,踩坑记录

本帖最后由 mosheng 于 2025-4-10 17:24 编辑

注意GetDefaultTabBrowser这里,如果是单窗口浏览器就很好处理,返回默认的前台浏览器即可
如果是创建了多个窗口的浏览器,就需要判断是哪个浏览器打开的浏览器插件,目前我的解决方法是字典存储插件浏览器与主浏览器的关联关系 (浏览器ID -> 主浏览器ID)
如果独立缓存的浏览器加载插件,独立缓存采用的是独立环境,所以独立的环境就要用独立的环境加载插件而不能用全局的

using FBroSharp;
using FBroSharp.Const;
using FBroSharp.DataType;
using FBroSharp.Event;
using FBroSharp.Lib;
using FBroSharp.Value;
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace BaseTest
{
    //public class ExtensionHandler : FBroSharpExtensionHandler
    //{
    //    // 基本构造函数
    //    public ExtensionHandler() : base()
    //    {
    //      Console.WriteLine("创建扩展处理器");
    //    }
    //}
    public class ExtensionHandler : FBroSharpExtensionHandler
    {
      //
      // 摘要:
      //   扩展插件_加载错误信息
      public override void OnExtensionLoadFailedMessage(string error, string path)
      {
            Console.WriteLine("扩展插件加载失败:" + error + ",路径:" + path);
      }

      //
      // 摘要:
      //   扩展插件_加载失败
      //
      //   Called if the CefRequestContext::LoadExtension request fails. |result| will be
      //   the error code.
      public override void OnExtensionLoadFailed(int result)
      {
            Console.WriteLine("扩展插件加载失败:" + result);
      }

      //
      // 摘要:
      //   扩展插件_加载成功
      //
      //   Called if the CefRequestContext::LoadExtension request succeeds. |extension|
      //   is the loaded extension.
      public override void OnExtensionLoaded(IFBroSharpExtension extension)
      {
            string extensionId = extension.GetIdentifier();
            string extensionPath = extension.GetPath();
            Console.WriteLine("扩展插件加载成功:" + extensionId + ", " + extensionPath);

            // 存储扩展ID到Form1的静态字段中
            定制软件.Form1.ExtensionId = extensionId;
            
            // 根据插件路径判断是哪个插件
            string lowerPath = extensionPath.ToLower();
            if (lowerPath.Contains("douyin"))
            {
                定制软件.Form1.DouyinExtensionId = extensionId;
                Console.WriteLine("抖音插件ID已保存: " + extensionId);
            }
            else if (lowerPath.Contains("xhs"))
            {
                定制软件.Form1.XhsExtensionId = extensionId;
                Console.WriteLine("小红书插件ID已保存: " + extensionId);
            }
      }

      //
      // 摘要:
      //   扩展插件_卸载
      //
      //   Called after the CefExtension::Unload request has completed.
      public override void OnExtensionUnloaded(IFBroSharpExtension extension)
      {
            Console.WriteLine("扩展插件卸载:" + extension.GetIdentifier(), extension.GetPath());
      }

      //
      // 摘要:
      //   扩展插件_即将加载Background浏览器
      //
      //   Called when an extension needs a browser to host a background script specified
      //   via the "background" manifest key. The browser will have no visible window and
      //   cannot be displayed. |extension| is the extension that is loading the background
      //   script. |url| is an internally generated reference to an HTML page that will
      //   be used to load the background script via a "<script>" src attribute. To allow
      //   creation of the browser optionally modify |client| and |settings| and return
      //   false. To cancel creation of the browser (and consequently cancel load of the
      //   background script) return true. Successful creation will be indicated by a call
      //   to CefLifeSpanHandler::OnAfterCreated, and CefBrowserHost::IsBackgroundHost will
      //   return true for the resulting browser. See https://developer.chrome.com/extensions/event_pages
      //   for more information about extension background script usage.
      public override bool OnBeforeBackgroundBrowser(IFBroSharpExtension extension, string url, IFBroSharpUseExtraData user_settings, ref FBroSharpBrowserSetting settings)
      {
            Console.WriteLine("扩展插件即将加载Background浏览器:" + extension.GetIdentifier(), extension.GetPath());
            return false;
      }

      //
      // 摘要:
      //   扩展插件_即将加载浏览器
      //
      //   Called when an extension API (e.g. chrome.tabs.create) requests creation of a
      //   new browser. |extension| and |browser| are the source of the API call. |active_browser|
      //   may optionally be specified via the windowId property or returned via the GetActiveBrowser()
      //   callback and provides the default |client| and |settings| values for the new
      //   browser. |index| is the position value optionally specified via the index property.
      //   |url| is the URL that will be loaded in the browser. |active| is true if the
      //   new browser should be active when opened. To allow creation of the browser optionally
      //   modify |windowInfo|, |client| and |settings| and return false. To cancel creation
      //   of the browser return true. Successful creation will be indicated by a call to
      //   CefLifeSpanHandler::OnAfterCreated. Any modifications to |windowInfo| will be
      //   ignored if |active_browser| is wrapped in a CefBrowserView.
      public override bool OnBeforeBrowser(IFBroSharpExtension extension, IFBroSharpBrowser browser, IFBroSharpBrowser active_browser, int index, string url, bool active, out FBroSharpWindowsInfo windowInfo, IFBroSharpUseExtraData user_settings, ref FBroSharpBrowserSetting settings)
      {
            Console.WriteLine("扩展插件即将加载浏览器:" + extension.GetIdentifier(), extension.GetPath());
            windowInfo = default(FBroSharpWindowsInfo);
            return false;
      }

      //
      // 摘要:
      //   扩展插件_获取执行浏览器
      //
      //   Called when no tabId is specified to an extension API call that accepts a tabId
      //   parameter (e.g. chrome.tabs.*). |extension| and |browser| are the source of the
      //   API call. Return the browser that will be acted on by the API call or return
      //   NULL to act on |browser|. The returned browser must share the same CefRequestContext
      //   as |browser|. Incognito browsers should not be considered unless the source extension
      //   has incognito access enabled, in which case |include_incognito| will be true.
      public override IFBroSharpBrowser GetActiveBrowser(IFBroSharpExtension extension, IFBroSharpBrowser browser, bool include_incognito)
      {
            Console.WriteLine("扩展插件获取执行浏览器:" + extension.GetIdentifier(), extension.GetPath());
            return null;
      }

      //
      // 摘要:
      //   扩展插件_获取当前标签默认浏览器
      //自定义添加事件,为了兼容tab获取当前默认tab,通过此事件将当前默认浏览器返回给插件,一般用于插件chrome.tab.reload执行的目标,
      //因为cef是没有tab概念无法直接获取默认浏览器所有通过此事件由自己控制返回默认浏览器,
      //如不返回将使用插件本身浏览器作为默认浏览器
      //   返回默认tab浏览器
      public override IFBroSharpBrowser GetDefaultTabBrowser(IFBroSharpExtension extension, IFBroSharpBrowser browser)
      {
            // 获取插件浏览器ID
            int pluginBrowserId = browser.GetIdentifier();
            
            // 尝试查找关联的主浏览器ID
            if (BaseTest.BrowserDis.PluginToMainBrowserMap.TryGetValue(pluginBrowserId, out int mainBrowserId))
            {
                Console.WriteLine($"找到关联的主浏览器: 插件浏览器ID={pluginBrowserId}, 主浏览器ID={mainBrowserId}");
               
                // 查找对应ID的主浏览器实例
                foreach (var mainBrowser in BaseTest.BrowserList.data)
                {
                  if (mainBrowser.GetIdentifier() == mainBrowserId)
                  {
                        Console.WriteLine("成功获取主浏览器实例");
                        return mainBrowser;
                  }
                }
            }
            
            Console.WriteLine($"未找到关联的主浏览器: 插件浏览器ID={pluginBrowserId}");
            return null;
      }

      //
      // 摘要:
      //   扩展插件_获取扩展资源
      //
      //   Called when the tabId associated with |target_browser| is specified to an extension
      //   API call that accepts a tabId parameter (e.g. chrome.tabs.*). |extension| and
      //   |browser| are the source of the API call. Return true to allow access of false
      //   to deny access. Access to incognito browsers should not be allowed unless the
      //   source extension has incognito access enabled, in which case |include_incognito|
      //   will be true.
      public override bool CanAccessBrowser(IFBroSharpExtension extension, IFBroSharpBrowser browser, bool include_incognito, IFBroSharpBrowser target_browser)
      {
            Console.WriteLine("扩展插件获取扩展资源:" + extension.GetIdentifier(), extension.GetPath());
            return false;
      }

      //
      // 摘要:
      //   扩展插件_获取扩展资源
      //
      //   Called to retrieve an extension resource that would normally be loaded from disk
      //   (e.g. if a file parameter is specified to chrome.tabs.executeScript). |extension|
      //   and |browser| are the source of the resource request. |file| is the requested
      //   relative file path. To handle the resource request return true and execute |callback|
      //   either synchronously or asynchronously. For the default behavior which reads
      //   the resource from the extension directory on disk return false. Localization
      //   substitutions will not be applied to resources handled via this method.
      public override bool GetExtensionResource(IFBroSharpExtension extension, IFBroSharpBrowser browser, string file)
      {
            Console.WriteLine("扩展插件获取扩展资源:" + extension.GetIdentifier(), extension.GetPath());
            return false;
      }
    }
}

itniao 发表于 2026-2-16 21:02:11

这么细节。你太赞了。!!!
页: [1]
查看完整版本: C#自定义扩展插件事件,踩坑记录