Как начать разработку расширений для Internet Explorer?


207

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

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

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

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

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

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

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


1
ИМХО IE 9 на порядки лучше предыдущих версий. (Конечно, я не оставлю Chrome для IE ... пока что нет.)
user541686

1
@ Алекс: какие вещи вы планируете реализовать в IE, чтобы мы могли начать копать в правильном общем направлении?
GregC

@ Алекс: Чтобы разбить эту проблему на управляемые части, мне нужно знать следующее: можем ли мы предположить, что конечный пользователь будет работать с IE9 и захочет установить среду выполнения dotNET 4.0?
GregC

Я согласен с GregC. Еще немного информации поможет здесь. Думаете ли вы о чем-то вроде панели инструментов, или о чем-то, что будет предварительно обрабатывать то, что просматривает пользователь, или о чем-то, что будет подключаться к сторонней службе.
облачный ворон

4
@ Алекс, взгляни на Кроссрайдер . Это сделает вашу жизнь намного проще.
Шдев

Ответы:


229

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

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

Я использую Visual Studio 2017 Community , 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и ОК 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" / отменить регистрацию "$ (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 \ x64 \ gacutil.exe

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

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

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

% windir% \ Microsoft.NET \ Framework 64 \ 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и ОК 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 \ x64 \ gacutil.exe" / f / i "$ (TargetDir) $ (TargetFileName)"
    
    "C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" / отменить регистрацию "$ (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 дня я вернусь, но я постараюсь приехать сюда тем временем.


2
Привет, я сделал именно то, что описано в ответе. Кнопка появляется. Exec funtion выполняется. Однако функции SetSite и GetSite никогда не вызываются. Я хочу знать URL страницы, на которой я нахожусь. Не удается вызвать эти методы для инициализации браузера. Пожалуйста, помогите
mustafabar

3
Я попытался сделать это в IE9 и: 1. Если в пути вашего проекта есть пробелы: вместо $(TargetDir)$(TargetFileName)использования "$(TargetDir)$(TargetFileName)" 2. Если вы используете Visual Studio 2010 Express, вы, вероятно, (я не) не вижу опцию « Запустить внешнюю программу» на вкладке «Отладка» - я просто запустите IE и перейдите по указанному URL-адресу 3. Кажется, он не работает в IE9 - я могу открыть форму (параметры выделения), но я не знаю, как заставить ее выделять текст
pinus.acer

8
Для ссылки Interop.SHDocVw - вместо этого вы должны добавить ссылку COM в «Microsoft Internet Controls», а затем «using SHDocVw;»
Эрик Хартфорд,

8
«IE10 в 64-разрядной Windows 8 не будет загружать ваше дополнение при запуске, если вы не соберетесь с архитектурой« Любой ЦП »и зарегистрируетесь с использованием как 32-, так и 64-битного RegAsm.exe». был отредактирован кем-то, кто был отклонен.
Мацеманн

3
Пожалуйста, смотрите продолжение: stackoverflow.com/questions/22953571/…

12

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

http://www.crossrider.org

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


Да, это действительно правильный путь, так как избегая кошмара, который развивает плагин в visual studio, это означает, что вы должны написать свой плагин только один раз для всех браузеров. Это также означает отсутствие необходимости разработки на виртуальной машине, если вы пользователь Mac.
opsb

11

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

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 ++)


6

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

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


4
C # 4.0 может быть лучше в этом отношении, так как COM Interop значительно улучшен.
Роберт Харви,

@ Роберт: Правда? Я понятия не имел ... в чем различия?
user541686

@ Mehrdad: Вы можете почувствовать разницу здесь: devx.com/dotnet/Article/42590/1954 . Более подробное обсуждение см. В выступлении Андерса Хейлсберга «Будущее C #» здесь: channel9.msdn.com/Blogs/pdc2008/TL16
Роберт Харви,

1
@Robert @Mehrdad: Не совсем. Это не COM-взаимодействие, которое является странным (в этом отношении) , оно разрабатывает и регистрирует COM-модуль, с которым не помогают новые функции C # 4.0.
BlueRaja - Дэнни Пфлугхофт

4

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

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

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

ИЛИ

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

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

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


Самый большой недостаток использования C # (это направление, в котором движется большинство других постеров) - это то, что он будет проходить через все виды дополнительных слоев, с обходным путем и патчами для кода, который будет встроен в C ++.
Линн рушится



3

Это, очевидно, решаемо , но для других пользователей я бы порекомендовал 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


0

Сердечно предлагаю вам этот пост Павла Зольникова, опубликованный в 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 Наслаждайтесь!


Нам нравится, чтобы ответы содержались в StackOverflow. Все, что этот пост действительно говорит мне, это «использовать объекты Band и .Net 2.0». Не могли бы вы включить пример кода здесь, чтобы показать, как это можно сделать?
Teepeemm

0

Вопрос с 2013 года, сейчас 2020, но может быть полезным для будущих посетителей.

Я пытался реализовать ответ @Miguel Angelo, в начале он не работал.

Там еще есть некоторые настройки, которые вам определятся.

в Internet Explorer (я использую IE-11) перейти к Tools-->Internet Options-->Advanced: введите описание изображения здесь

введите описание изображения здесь

Также посмотрите этот ТАК вопрос и этот пример из github


-2

введите описание изображения здесь

На вкладке «События сборки» установите для командной строки событий после сборки значение: (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)"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.