Как начать разработку расширений для Internet Explorer? - PullRequest
203 голосов
/ 13 апреля 2011

Есть ли у кого-нибудь здесь опыт в / в разработке расширений IE, которые могут поделиться своими знаниями? Это может включать примеры кода, или ссылки на хорошие, или документацию по процессу, или что-нибудь еще.

Я действительно хочу это сделать, но я попадаю в гигантскую стену с паршивой документацией, паршивым кодом / примером кода / его отсутствием. Будем весьма благодарны за любую помощь / ресурсы, которые вы можете предложить.

В частности, я хотел бы начать с того, как получить доступ к DOM / манипулировать им из расширения IE.

РЕДАКТИРОВАТЬ, даже больше деталей:

В идеале я бы хотел установить кнопку на панели инструментов, чтобы при нажатии на нее появлялось меню, содержащее ссылки на внешние сайты. Я также хотел бы получить доступ к DOM и установить JavaScript на странице в зависимости от некоторых условий.

Каков наилучший способ сохранить информацию в расширении IE? В Firefox / Chrome / большинстве современных браузеров вы используете window.localStorage, но, очевидно, в IE8 / IE7 это не вариант. Может быть, БД SQLite или такой? Можно предположить, что .NET 4.0 будет установлен на компьютере пользователя?

Я не хочу использовать Spice IE, поскольку я хочу создать тот, который также совместим с IE9. Я также добавил тег C ++ к этому вопросу, потому что, если его лучше создать в C ++, я могу это сделать.

Ответы [ 10 ]

223 голосов
/ 21 апреля 2011

[ОБНОВЛЕНИЕ] Я обновляю этот ответ для работы с Internet Explorer 11 , в Windows 10 x64 с Visual Studio 2017 Community .Предыдущая версия этого ответа (для Internet Explorer 8, в Windows 7 x64 и Visual Studio 2010) находится в нижней части этого ответа.

Создание работающей надстройки Internet Explorer 11

Я использую Сообщество Visual Studio 2017 , C # , .Net Framework 4.6.1 , поэтому некоторые из этих шагов могут немного отличаться для вас.

Вам нужно открыть Visual Studio от имени администратора , чтобы построить решение, чтобы сценарий после сборки мог зарегистрировать BHO (необходим доступ к реестру).

Начните с создания классабиблиотека.Я назвал мой InternetExplorerExtension .

Добавьте эти ссылки в проект:

  • Interop.SHDocVw: вкладка COM / поиск "Microsoft Internet Controls"
  • Microsoft.mshtml: вкладка «Сборки» / поиск для "Microsoft.mshtml"

Примечание: Каким-то образом MSHTML не был зарегистрирован в моей системе, хотя я мог найти его в окне Добавить ссылку,Это вызвало ошибку при сборке:

Не удалось найти сборку оболочки для библиотеки типов "MSHTML"

Исправление можно найти по адресу http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html Или выможно запустить этот пакетный скрипт:

"%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
cd "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\PublicAssemblies"
regasm Microsoft.mshtml.dll
gacutil /i Microsoft.mshtml.dll

Создать следующие файлы:

IEAddon.cs

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
using mshtml;
using SHDocVw;

namespace InternetExplorerExtension
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("D40C654D-7C51-4EB3-95B2-1E23905C2A2D")]
    [ProgId("MyBHO.WordHighlighter")]
    public class WordHighlighterBHO : IObjectWithSite, IOleCommandTarget
    {
        const string DefaultTextToHighlight = "browser";

        IWebBrowser2 browser;
        private object site;

        #region Highlight Text
        void OnDocumentComplete(object pDisp, ref object URL)
        {
            try
            {
                // @Eric Stob: Thanks for this hint!
                // This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
                //if (pDisp != this.site)
                //    return;

                var document2 = browser.Document as IHTMLDocument2;
                var document3 = browser.Document as IHTMLDocument3;

                var window = document2.parentWindow;
                window.execScript(@"function FncAddedByAddon() { alert('Message added by addon.'); }");

                Queue<IHTMLDOMNode> queue = new Queue<IHTMLDOMNode>();
                foreach (IHTMLDOMNode eachChild in document3.childNodes)
                    queue.Enqueue(eachChild);

                while (queue.Count > 0)
                {
                    // replacing desired text with a highlighted version of it
                    var domNode = queue.Dequeue();

                    var textNode = domNode as IHTMLDOMTextNode;
                    if (textNode != null)
                    {
                        if (textNode.data.Contains(TextToHighlight))
                        {
                            var newText = textNode.data.Replace(TextToHighlight, "<span style='background-color: yellow; cursor: hand;' onclick='javascript:FncAddedByAddon()' title='Click to open script based alert window.'>" + TextToHighlight + "</span>");
                            var newNode = document2.createElement("span");
                            newNode.innerHTML = newText;
                            domNode.replaceNode((IHTMLDOMNode)newNode);
                        }
                    }
                    else
                    {
                        // adding children to collection
                        var x = (IHTMLDOMChildrenCollection)(domNode.childNodes);
                        foreach (IHTMLDOMNode eachChild in x)
                        {
                            if (eachChild is mshtml.IHTMLScriptElement)
                                continue;
                            if (eachChild is mshtml.IHTMLStyleElement)
                                continue;

                            queue.Enqueue(eachChild);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion
        #region Load and Save Data
        static string TextToHighlight = DefaultTextToHighlight;
        public static string RegData = "Software\\MyIEExtension";

        [DllImport("ieframe.dll")]
        public static extern int IEGetWriteableHKCU(ref IntPtr phKey);

        private static void SaveOptions()
        {
            // In IE 7,8,9,(desktop)10 tabs run in Protected Mode
            // which prohibits writes to HKLM, HKCU.
            // Must ask IE for "Writable" registry section pointer
            // which will be something like HKU/S-1-7***/Software/AppDataLow/
            // In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
            // where BHOs are not allowed to run, except in edge cases.
            // see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
            IntPtr phKey = new IntPtr();
            var answer = IEGetWriteableHKCU(ref phKey);
            RegistryKey writeable_registry = RegistryKey.FromHandle(
                new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
            );
            RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);

            if (registryKey == null)
                registryKey = writeable_registry.CreateSubKey(RegData);
            registryKey.SetValue("Data", TextToHighlight);

            writeable_registry.Close();
        }
        private static void LoadOptions()
        {
            // In IE 7,8,9,(desktop)10 tabs run in Protected Mode
            // which prohibits writes to HKLM, HKCU.
            // Must ask IE for "Writable" registry section pointer
            // which will be something like HKU/S-1-7***/Software/AppDataLow/
            // In "metro" IE 10 mode, tabs run in "Enhanced Protected Mode"
            // where BHOs are not allowed to run, except in edge cases.
            // see http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
            IntPtr phKey = new IntPtr();
            var answer = IEGetWriteableHKCU(ref phKey);
            RegistryKey writeable_registry = RegistryKey.FromHandle(
                new Microsoft.Win32.SafeHandles.SafeRegistryHandle(phKey, true)
            );
            RegistryKey registryKey = writeable_registry.OpenSubKey(RegData, true);

            if (registryKey == null)
                registryKey = writeable_registry.CreateSubKey(RegData);
            registryKey.SetValue("Data", TextToHighlight);

            if (registryKey == null)
            {
                TextToHighlight = DefaultTextToHighlight;
            }
            else
            {
                TextToHighlight = (string)registryKey.GetValue("Data");
            }
            writeable_registry.Close();
        }
        #endregion

        [Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
        [InterfaceType(1)]
        public interface IServiceProvider
        {
            int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
        }

        #region Implementation of IObjectWithSite
        int IObjectWithSite.SetSite(object site)
        {
            this.site = site;

            if (site != null)
            {
                LoadOptions();

                var serviceProv = (IServiceProvider)this.site;
                var guidIWebBrowserApp = Marshal.GenerateGuidForType(typeof(IWebBrowserApp)); // new Guid("0002DF05-0000-0000-C000-000000000046");
                var guidIWebBrowser2 = Marshal.GenerateGuidForType(typeof(IWebBrowser2)); // new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
                IntPtr intPtr;
                serviceProv.QueryService(ref guidIWebBrowserApp, ref guidIWebBrowser2, out intPtr);

                browser = (IWebBrowser2)Marshal.GetObjectForIUnknown(intPtr);

                ((DWebBrowserEvents2_Event)browser).DocumentComplete +=
                    new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
            }
            else
            {
                ((DWebBrowserEvents2_Event)browser).DocumentComplete -=
                    new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
                browser = null;
            }
            return 0;
        }
        int IObjectWithSite.GetSite(ref Guid guid, out IntPtr ppvSite)
        {
            IntPtr punk = Marshal.GetIUnknownForObject(browser);
            int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
            Marshal.Release(punk);
            return hr;
        }
        #endregion
        #region Implementation of IOleCommandTarget
        int IOleCommandTarget.QueryStatus(IntPtr pguidCmdGroup, uint cCmds, ref OLECMD prgCmds, IntPtr pCmdText)
        {
            return 0;
        }
        int IOleCommandTarget.Exec(IntPtr pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            try
            {
                // Accessing the document from the command-bar.
                var document = browser.Document as IHTMLDocument2;
                var window = document.parentWindow;
                var result = window.execScript(@"alert('You will now be allowed to configure the text to highlight...');");

                var form = new HighlighterOptionsForm();
                form.InputText = TextToHighlight;
                if (form.ShowDialog() != DialogResult.Cancel)
                {
                    TextToHighlight = form.InputText;
                    SaveOptions();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return 0;
        }
        #endregion

        #region Registering with regasm
        public static string RegBHO = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
        public static string RegCmd = "Software\\Microsoft\\Internet Explorer\\Extensions";

        [ComRegisterFunction]
        public static void RegisterBHO(Type type)
        {
            string guid = type.GUID.ToString("B");

            // BHO
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
                if (registryKey == null)
                    registryKey = Registry.LocalMachine.CreateSubKey(RegBHO);
                RegistryKey key = registryKey.OpenSubKey(guid);
                if (key == null)
                    key = registryKey.CreateSubKey(guid);
                key.SetValue("Alright", 1);
                registryKey.Close();
                key.Close();
            }

            // Command
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
                if (registryKey == null)
                    registryKey = Registry.LocalMachine.CreateSubKey(RegCmd);
                RegistryKey key = registryKey.OpenSubKey(guid);
                if (key == null)
                    key = registryKey.CreateSubKey(guid);
                key.SetValue("ButtonText", "Highlighter options");
                key.SetValue("CLSID", "{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}");
                key.SetValue("ClsidExtension", guid);
                key.SetValue("Icon", "");
                key.SetValue("HotIcon", "");
                key.SetValue("Default Visible", "Yes");
                key.SetValue("MenuText", "&Highlighter options");
                key.SetValue("ToolTip", "Highlighter options");
                //key.SetValue("KeyPath", "no");
                registryKey.Close();
                key.Close();
            }
        }

        [ComUnregisterFunction]
        public static void UnregisterBHO(Type type)
        {
            string guid = type.GUID.ToString("B");
            // BHO
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegBHO, true);
                if (registryKey != null)
                    registryKey.DeleteSubKey(guid, false);
            }
            // Command
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(RegCmd, true);
                if (registryKey != null)
                    registryKey.DeleteSubKey(guid, false);
            }
        }
        #endregion
    }
}

Interop.cs

using System;
using System.Runtime.InteropServices;
namespace InternetExplorerExtension
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
    public interface IObjectWithSite
    {
        [PreserveSig]
        int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
        [PreserveSig]
        int GetSite(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)]out IntPtr ppvSite);
    }


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OLECMDTEXT
    {
        public uint cmdtextf;
        public uint cwActual;
        public uint cwBuf;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public char rgwz;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct OLECMD
    {
        public uint cmdID;
        public uint cmdf;
    }

    [ComImport(), ComVisible(true),
    Guid("B722BCCB-4E68-101B-A2BC-00AA00404770"),
    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IOleCommandTarget
    {

        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int QueryStatus(
            [In] IntPtr pguidCmdGroup,
            [In, MarshalAs(UnmanagedType.U4)] uint cCmds,
            [In, Out, MarshalAs(UnmanagedType.Struct)] ref OLECMD prgCmds,
            //This parameter must be IntPtr, as it can be null
            [In, Out] IntPtr pCmdText);

        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int Exec(
            //[In] ref Guid pguidCmdGroup,
            //have to be IntPtr, since null values are unacceptable
            //and null is used as default group!
            [In] IntPtr pguidCmdGroup,
            [In, MarshalAs(UnmanagedType.U4)] uint nCmdID,
            [In, MarshalAs(UnmanagedType.U4)] uint nCmdexecopt,
            [In] IntPtr pvaIn,
            [In, Out] IntPtr pvaOut);
    }
}

и, наконец, форма, которую мы будем использовать для настройки параметров.В этой форме поместите TextBox и Ok Button.Установите DialogResult кнопки на Ok .Поместите этот код в код формы:

using System.Windows.Forms;
namespace InternetExplorerExtension
{
    public partial class HighlighterOptionsForm : Form
    {
        public HighlighterOptionsForm()
        {
            InitializeComponent();
        }

        public string InputText
        {
            get { return this.textBox1.Text; }
            set { this.textBox1.Text = value; }
        }
    }
}

В свойствах проекта сделайте следующее:

  • Подпишите сборку с помощью сильной клавиши;
  • На вкладке «Отладка» установите Запустить внешнюю программу на C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • На вкладке «Отладка» установите Аргументы командной строки на http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • На вкладке «События сборки» установите Командная строка событий после сборки в:

    "%ProgramFiles(x86)%\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
    
    "%windir%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
    
    "%windir%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

Внимание: , хотя мойкомпьютер x64, я использовал путь не x64 gacutil.exe, и он работал ... один, специфичный для x64, находится по адресу:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\<b>x64\</b>gacutil.exe

64bit IE Требуется 64bit-Скомпилировано и зарегистрировано 64-битное BHO.Хотя я мог отлаживать только с помощью 32-разрядного IE11, зарегистрированное 32-разрядное расширение также работало, запустив 64-разрядный IE11.

Этот ответ содержит дополнительную информацию об этом: https://stackoverflow.com/a/23004613/195417

Если вам нужно, вы можете использовать 64-битный регазм:

%windir%\Microsoft.NET\Framework<b>64\</b>v4.0.30319\RegAsm.exe

Как работает это дополнение

Я не изменил поведение дополнения ...взгляните на раздел IE8 ниже для описания.


## Предыдущий ответ для IE8

Человек ... это было много работы!Мне было так любопытно, как это сделать, что я сделал это сам.

Прежде всего ... кредит - это не все мое.Это компиляция того, что я нашел на этих сайтах:

И, конечно, я хотел, чтобы в моем ответе были запрошенные вами функции:

  • Обход DOM для поиска чего-либо;
  • кнопка, которая показывает окно (в моем случае для настройки)
  • сохранить конфигурацию (для этого я буду использовать реестр)
  • и, наконец, выполнить javascript.

Я опишу это шаг за шагом, как мне удалось это сделать, работая с Internet Explorer 8 , в Windows 7 x64 ... обратите внимание, что я не смог протестировать в других конфигурации. Надеюсь, вы понимаете =)

Создание работающей надстройки Internet Explorer 8

Я использую Visual Studio 2010 , C # 4 , .Net Framework 4 , поэтому некоторые из этих шагов могут немного отличаться для вас.

Создана библиотека классов. Я назвал мой InternetExplorerExtension .

Добавьте эти ссылки на проект:

  • Interop.SHDocVw
  • Microsoft.mshtml

Примечание. Эти ссылки могут находиться в разных местах на каждом компьютере.

это то, что содержит мой раздел ссылок в csproj:

<Reference Include="Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyToken=90ba9c70f846762e, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <EmbedInteropTypes>True</EmbedInteropTypes>
  <HintPath>C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\Interop.SHDocVw.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.mshtml, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  <EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />

Создайте файлы так же, как обновленные файлы IE11.

IEAddon.cs

Вы можете раскомментировать следующие строки из версии IE11:

...
// @Eric Stob: Thanks for this hint!
// This was used to prevent this method being executed more than once in IE8... but now it seems to not work anymore.
if (pDisp != this.site)
    return;
...

Interop.cs

То же, что и в версии IE11.

и, наконец, форма, которую мы будем использовать для настройки параметров. В этой форме поместите TextBox и Ok Button. Установите DialogResult кнопки на Ok . Код такой же для аддона IE11.

В свойствах проекта сделайте следующее:

  • Подписать сборку клавишей;
  • На вкладке «Отладка» установите Запустить внешнюю программу на C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • На вкладке «Отладка» установите Аргументы командной строки на http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • На вкладке «События сборки» установите Командная строка событий после сборки в:

    "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\<strong>x64</strong>\gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
    
    "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
    
    "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

Внимание: так как мой компьютер x64, на пути к исполняемому файлу gacutil на моем компьютере есть определенный x64, который может отличаться на вашем.

64-битный IE Требуется 64-битная компиляция и 64-битная регистрация BHO. Используйте 64-битный RegAsm.exe (обычно находится в C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Как работает это дополнение

Обходит все дерево DOM, заменяя текст, настроенный с помощью кнопки, на желтый фон. Если вы нажмете на пожелтевшие тексты, он вызовет функцию JavaScript, которая была вставлена ​​на страницу динамически. Слово по умолчанию - «браузер», так что оно соответствует большинству из них! РЕДАКТИРОВАТЬ: после изменения строки, которая будет выделена, вы должны щелкнуть поле URL и нажать Enter ... F5 не будет работать, я думаю, что это потому, что F5 рассматривается как «навигация», и это будет Требуется прослушать событие навигации (возможно). Я постараюсь это исправить позже.

Теперь пришло время уходить. Я очень устал. Не стесняйтесь задавать вопросы ... возможно, я не смогу ответить, так как я собираюсь в путешествие ... через 3 дня я вернусь, но я постараюсь приехать сюда тем временем.

13 голосов
/ 12 декабря 2011

Еще один крутой подход - проверить:

http://www.crossrider.org

Это основа, основанная на JS с jquery, которая позволяет разрабатывать расширения для браузеров для IE, FF и Chrome, используя одинобщий код JS.По сути, фреймворк выполняет всю отвратительную работу, и у вас остается написание кода приложений.

11 голосов
/ 13 апреля 2011

Состояние расширений IE на самом деле довольно печальное. У вас есть старая модель IE5 Browser Helper Object (да, те печально известные BHO, которые все любили блокировать в прошлом), панели инструментов и новые ускорители для IE. Даже тогда совместимость иногда будет нарушаться. Я имел обыкновение поддерживать расширение для IE6, которое порвалось с IE7, поэтому есть некоторые вещи, которые изменились. По большей части, насколько я знаю (я не касался BHOs ​​в течение многих лет), вам все еще нужно кодировать их с использованием Active Template Libraries (вроде STL для Microsoft COM), а также только для C ++. Вы могли бы сделать COM Interop с C # и уйти с этим в C #, но это, вероятно, будет слишком сложно для того, чтобы оно того стоило. В любом случае, если вы заинтересованы в написании собственного расширения для IE (что вполне вероятно, если вы хотите, чтобы ваши расширения были доступны во всех основных браузерах), вот официальные ресурсы Microsoft.

http://msdn.microsoft.com/en-us/library/aa753587(v=vs.85).aspx

А для новых ускорителей в IE8 вы можете проверить этот.

http://msdn.microsoft.com/en-us/library/cc289775(v=vs.85).aspx

Я согласен, что документация ужасна, а API довольно устарели. Тем не менее, я надеюсь, что это поможет.

РЕДАКТИРОВАТЬ: Я думаю, что я могу добавить один последний источник информации здесь. Я просматривал свои записи назад, когда работал над BHO. И это статья, которая заставила меня начать с них. Он довольно старый, но имеет хорошее объяснение интерфейсов ATL, которые вы будете использовать при работе с IE BHO (например, IObjectWithSite). Я думаю, что это довольно хорошо объяснено и помогло мне много тогда. http://msdn.microsoft.com/en-us/library/bb250436.aspx Я также проверил пример, который опубликовал GregC. Он работает как минимум с IE8 и совместим с VS 2010, поэтому, если вы хотите использовать C #, вы можете начать там и взглянуть на книгу Джона Скита. (C # в Depth 2nd edition) Глава 13 содержит много информации о новых функциях в C # 4, которые вы можете использовать для улучшения взаимодействия с COM. (Я бы все еще рекомендовал вам делать надстройку в C ++)

7 голосов
/ 16 апреля 2011

Разработка C # BHO - это боль в заднице.Он включает в себя много неприличного COM-кода и вызовов p / invoke.

У меня есть в основном законченный C # BHO здесь , который вы можете использовать для источника длячто вы хотите.Я говорю "в основном" , потому что я так и не понял, как сохранить данные приложения в защищенном режиме IE .

5 голосов
/ 16 апреля 2011

Я работаю с браузерным браузером IE уже много лет, и в ходе одного и того же поиска снова и снова появляется одно имя: Игорь Тандетник

Если бы я разрабатывал расширение, я бы нацелился на BHO и начал поискать в Google:

БХО Игорь Тандетник

ИЛИ

Browser Helper Object Игорь Тандетник

Его сообщения часто очень подробны, и он знает, о чем говорит.

Вы найдете себя в курсе программирования COM и ATL. Для примера прохождения, проверьте: http://msdn.microsoft.com/en-us/library/ms976373.aspx

3 голосов
/ 05 мая 2012

Это явно решаемо, но для других пользователей я бы порекомендовал SpicIE framework . Я сделал собственное расширение на его основе. Он официально поддерживает только Internet Explorer 7/8, но я проверил это в Internet Explorer 6-10 (от Windows XP до Windows 8 Consumer Preview), и он отлично работает . К сожалению, в последнем выпуске были некоторые ошибки, поэтому мне пришлось их исправить и сделать свой собственный выпуск: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251

3 голосов
/ 19 апреля 2011

Если вы не пытаетесь изобретать велосипед, вы можете попробовать Добавить In Express для IE .Я использовал продукт для VSTO , и он довольно хорош.Также у них есть полезный форум и быстрая поддержка.

3 голосов
/ 16 апреля 2011

Я согласен с Робертом Харви, в C # 4.0 улучшено взаимодействие с COM.Вот немного более старого кода C #, в котором отчаянно требуется перезапись.

http://www.codeproject.com/KB/cs/Attach_BHO_with_C_.aspx

Это попытка упростить вещи, избегая ATL и переходя на Spartan COM:

C ++ и COM для запуска BHOs ​​

0 голосов
/ 07 сентября 2016

Я настоятельно рекомендую вам опубликовать этот пост Павла Зольникова в 2002 году!

http://www.codeproject.com/Articles/2219/Extending-Explorer-with-Band-Objects-using-NET-and

Он основан на использовании объектов Band и скомпилирован с использованием .Net 2.0.Исходный код предоставляется, открывается и хорошо компилируется с Visual Studio 2013. Как вы прочтете в комментариях к посту, он отлично работает для IE 11, Windows 7 и Windows 10. Он отлично работает для меня в Windows 7 + SP1 и IE.11 Наслаждайтесь!

0 голосов
/ 26 июля 2013

enter image description here

На вкладке «События сборки» установите для командной строки событий после сборки значение: (x64) указано ниже

"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\gacutil.exe" /if "$(TargetDir)$(TargetFileName)"    
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" /u "$(TargetDir)$(TargetFileName)"    
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"

Мне нужна вкладка «События сборки», в командной строке «События после сборки» (32-разрядная операционная система)

"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\gacutil.exe" /if "$(TargetDir)$(TargetFileName)"    
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /u "$(TargetDir)$(TargetFileName)"    
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"
...