Jak rozpocząć tworzenie rozszerzeń programu Internet Explorer?

207

Czy ktoś tutaj ma doświadczenie w opracowywaniu rozszerzeń IE, które mogą dzielić się swoją wiedzą? Obejmuje to próbki kodu, łącza do dobrych, dokumentację procesu lub cokolwiek innego.

Naprawdę chcę to zrobić, ale uderzam w gigantyczną ścianę z kiepską dokumentacją, kiepskim kodem / przykładowym kodem / jego brakiem. Każda pomoc / zasoby, które możesz zaoferować, byłyby bardzo mile widziane.

W szczególności chciałbym zacząć od sposobu uzyskania dostępu do DOM i manipulowania nim z poziomu rozszerzenia IE.

EDYCJA, jeszcze więcej szczegółów:

Idealnie chciałbym umieścić przycisk paska narzędzi, który po kliknięciu wyświetli menu zawierające linki do stron zewnętrznych. Chciałbym również uzyskać dostęp do DOM i umieścić JavaScript na stronie w zależności od niektórych warunków.

Jaki jest najlepszy sposób na zachowanie informacji w rozszerzeniu IE? W Firefox / Chrome / Większość nowoczesnych przeglądarek używaszwindow.localStorage , ale oczywiście w IE8 / IE7, to nie jest opcja. Może SQLite DB lub coś takiego? Czy można założyć, że .NET 4.0 zostanie zainstalowany na komputerze użytkownika?

Nie chcę używać Spice IE, ponieważ chcę zbudować taki, który jest również zgodny z IE9. Dodałem również tag C ++ do tego pytania, ponieważ jeśli lepiej jest zbudować jeden w C ++, mogę to zrobić.

Alex
źródło
1
IMHO IE 9 jest o rząd wielkości lepszy niż poprzednie wersje. (Nie że oczywiście zostawię Chrome na IE ... i tak jeszcze nie.)
user541686 16.04.11
1
@Alex: jakie rzeczy planujesz wdrożyć w IE, abyśmy mogli zacząć kopać we właściwym ogólnym kierunku?
GregC
@Alex: Aby podzielić ten problem na części możliwe do zarządzania, muszę wiedzieć, co następuje: czy możemy założyć, że użytkownik końcowy będzie korzystał z IE9 i będzie chciał zainstalować środowisko uruchomieniowe dotNET 4.0?
GregC
Zgadzam się z GregC. Tutaj znajdziesz więcej informacji. Zastanawiasz się nad czymś takim jak pasek narzędzi, czy może coś, co wstępnie przetworzy to, co użytkownik przegląda, lub coś, co połączy się z usługą strony trzeciej.
cloudraven
4
@Alex, spójrz na Crossrider . Ułatwi ci to życie.
shdev

Odpowiedzi:

229

[AKTUALIZACJA] Aktualizuję tę odpowiedź do pracy z programem Internet Explorer 11 w systemie Windows 10 x64 ze społecznością Visual Studio 2017 . Poprzednia wersja tej odpowiedzi (dla Internet Explorera 8, Windows 7 x64 i Visual Studio 2010) znajduje się na dole tej odpowiedzi.

Tworzenie działającego dodatku do programu Internet Explorer 11

Korzystam z Visual Studio 2017 Community , C # , .Net Framework 4.6.1 , więc niektóre z tych kroków mogą być nieco inne dla Ciebie.

Musisz otworzyć Visual Studio jako Administrator, aby zbudować rozwiązanie, aby skrypt po kompilacji mógł zarejestrować BHO (wymaga dostępu do rejestru).

Zacznij od utworzenia biblioteki klas. Zadzwoniłem do mojego InternetExplorerExtension .

Dodaj te odniesienia do projektu:

  • Interop.SHDocVw: karta COM / wyszukaj "Microsoft Internet Controls"
  • Microsoft.mshtml: karta Zespoły / wyszukaj "Microsoft.mshtml"

Uwaga: Jakoś MSHTML nie został zarejestrowany w moim systemie, chociaż mogłem znaleźć w oknie Dodaj odniesienie. Spowodowało to błąd podczas budowania:

Nie można znaleźć zespołu opakowania dla biblioteki typów „MSHTML”

Poprawka można znaleźć na stronie http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html Lub możesz uruchomić ten skrypt wsadowy:

"%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

Utwórz następujące pliki:

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);
    }
}

i wreszcie formularz, którego użyjemy do skonfigurowania opcji. W tej formie umieść a TextBoxi OK Button. Ustaw DialogResult przycisku na Ok . Umieść ten kod w kodzie formularza:

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; }
        }
    }
}

We właściwościach projektu wykonaj następujące czynności:

  • Podpisz zestaw silnym kluczem;
  • Na karcie Debugowanie ustaw opcję Uruchom program zewnętrzny naC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Na karcie Debugowanie ustaw Argumenty wiersza polecenia nahttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Na karcie Zdarzenia kompilacji ustaw wiersz polecenia Zdarzenia po kompilacji na:

    „% 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” / wyrejestruj „$ (TargetDir) $ (TargetFileName)”
    
    „% windir% \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe” „$ (TargetDir) $ (TargetFileName)”

Uwaga: mimo że mój komputer to x64, użyłem ścieżki innej niż x64 gacutil.exei zadziałało ... ta specyficzna dla x64 jest na:

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

64bit IE Potrzebuje skompilowanego i zarejestrowanego 64-bitowego BHO. Chociaż mogłem debugować tylko przy użyciu 32-bitowego IE11, zarejestrowane rozszerzenie 32-bitowe również działało, uruchamiając 64-bitowy IE11.

Ta odpowiedź zawiera dodatkowe informacje na ten temat: https://stackoverflow.com/a/23004613/195417

Jeśli potrzebujesz, możesz użyć 64-bitowego regasmu:

% windir% \ Microsoft.NET \ Framework 64 \ v4.0.30319 \ RegAsm.exe

Jak działa ten dodatek

Nie zmieniłem zachowania dodatku ... spójrz na opis poniżej sekcji IE8.


## Poprzednia odpowiedź dla IE8

Człowieku ... to było dużo pracy! Byłem tak ciekawy, jak to zrobić, że sam to zrobiłem.

Po pierwsze ... kredyt nie jest cały mój. To jest kompilacja tego, co znalazłem na tych stronach:

I oczywiście chciałem, aby moja odpowiedź zawierała funkcje, o które prosiłeś:

  • Przejście DOM, aby znaleźć coś;
  • przycisk, który pokazuje okno (w moim przypadku do konfiguracji)
  • zachowaj konfigurację (użyję do tego rejestru)
  • i wreszcie uruchom javascript.

Opiszę to krok po kroku, jak udało mi się to zrobić przy pomocy Internet Explorera 8 , w Windows 7 x64 ... zauważ, że nie mogłem testować w innych konfiguracjach. Mam nadzieję, że rozumiesz =)

Tworzenie działającego dodatku do programu Internet Explorer 8

Używam Visual Studio 2010 , C # 4 , .Net Framework 4 , więc niektóre z tych kroków mogą być nieco inne dla Ciebie.

Utworzono bibliotekę klas. Zadzwoniłem do mojego InternetExplorerExtension .

Dodaj te odniesienia do projektu:

  • Interop.SHDocVw
  • Microsoft.mshtml

Uwaga: te odniesienia mogą znajdować się w różnych miejscach na każdym komputerze.

oto, co zawiera moja sekcja referencji w 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" />

Utwórz pliki w taki sam sposób, jak zaktualizowane pliki IE11.

IEAddon.cs

Możesz odkomentować następujące wiersze z wersji 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

Taki sam jak wersja IE11.

i wreszcie formularz, którego użyjemy do skonfigurowania opcji. W tej formie umieść a TextBoxi OK Button. Ustaw DialogResult przycisku na Ok . Kod jest taki sam dla dodatku IE11.

We właściwościach projektu wykonaj następujące czynności:

  • Podpisz zestaw silnym kluczem;
  • Na karcie Debugowanie ustaw opcję Uruchom program zewnętrzny naC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Na karcie Debugowanie ustaw Argumenty wiersza polecenia nahttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Na karcie Zdarzenia kompilacji ustaw wiersz polecenia Zdarzenia po kompilacji na:

    „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” / wyrejestruj „$ (TargetDir) $ (TargetFileName)”
    
    „C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe” „$ (TargetDir) $ (TargetFileName)”

Uwaga: ponieważ moim komputerem jest x64, na ścieżce programu gacutil na moim komputerze znajduje się określony x64, który może być inny na twoim.

64bit IE Potrzebuje skompilowanego i zarejestrowanego 64-bitowego BHO. Użyj 64-bitowego RegAsm.exe (zwykle mieszka w C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Jak działa ten dodatek

Przechodzi przez całe drzewo DOM, zastępując tekst, skonfigurowany za pomocą przycisku, sam z żółtym tłem. Kliknięcie pożółkłych tekstów wywołuje funkcję javascript, która została dynamicznie wstawiona na stronie. Domyślnym słowem jest „przeglądarka”, więc pasuje do wielu z nich! EDYCJA: po zmianie ciągu, który ma być podświetlony, musisz kliknąć pole adresu URL i nacisnąć Enter ... F5 nie będzie działać, myślę, że dzieje się tak, ponieważ F5 jest uważane za „nawigację” i wymagałoby odsłuchania zdarzenia nawigacyjnego (może). Spróbuję to naprawić później.

Czas już iść. Jestem bardzo zmęczony. Zapraszam do zadawania pytań ... być może nie będę w stanie odpowiedzieć, ponieważ jadę na wycieczkę ... za 3 dni wrócę, ale w międzyczasie postaram się tu przyjechać.

Miguel Angelo
źródło
2
Cześć, zrobiłem dokładnie to, co opisano w odpowiedzi. Przycisk się pojawia. Funkcja wykonania jest wykonywana. Jednak funkcje SetSite i GetSite nigdy nie są wywoływane. Chcę znać adres URL strony, na której jestem. Nie można wywołać tych metod w celu zainicjowania przeglądarki. Proszę o pomoc
mustafabar
3
Próbowałem to zrobić na IE9 i: 1. Jeśli ścieżka projektu ma spacje: zamiast $(TargetDir)$(TargetFileName)używać "$(TargetDir)$(TargetFileName)" 2. Jeśli używasz programu Visual Studio 2010 Express, prawdopodobnie (tak) nie widzę opcji Uruchom program zewnętrzny na karcie Debugowanie - I po prostu uruchom IE i przejdź do podanego adresu URL 3. Wygląda na to, że nie działa na IE9 - mogę otworzyć formularz (opcje wyróżnienia), ale nie wiem, jak go podświetlić
pinus.acer
8
W przypadku odniesienia do Interop.SHDocVw - zamiast tego należy dodać odwołanie COM do „Microsoft Internet Controls”, a następnie „using SHDocVw;”
Eric Hartford,
8
„IE10 na x64 Windows 8 nie załaduje twojego dodatku podczas uruchamiania, chyba że zbudujesz z architekturą„ Any CPU ”i zarejestrujesz się przy użyciu 32- i 64-bitowego RegAsm.exe.” była zmianą dokonaną przez kogoś, kto został odrzucony.
Matsemann
3
Zobacz dalsze informacje: stackoverflow.com/questions/22953571/…
12

Kolejnym fajnym podejściem byłoby sprawdzenie:

http://www.crossrider.org

Jest to framework oparty na JS z jquery, który pozwala tworzyć rozszerzenia przeglądarek dla IE, FF i Chrome za pomocą jednego wspólnego kodu JS. Zasadniczo framework wykonuje całą paskudną pracę i nie musisz pisać kodu aplikacji.

Shaish
źródło
Tak, to jest naprawdę droga, a także unikanie koszmaru, który rozwija wtyczkę w Visual Studio, oznacza to, że musisz napisać wtyczkę tylko raz dla wszystkich przeglądarek. Oznacza to również, że nie musisz się rozwijać na maszynie wirtualnej, jeśli jesteś użytkownikiem komputera Mac.
opsb
11

Stan rozszerzeń IE jest naprawdę smutny. Masz stary model IE5 Browser Helper Object (tak, te niesławne BHO, które wszyscy lubili blokować w ciągu dnia), paski narzędzi i nowe akceleratory dla IE. Nawet wtedy zgodność czasami się psuje. Kiedyś utrzymywałem rozszerzenie dla IE6, które zepsuło się z IE7, więc niektóre rzeczy się zmieniły. W większości przypadków, o ile wiem (od lat nie dotykałem BHO), nadal musisz je kodować za pomocą Active Template Libraries (coś w rodzaju STL dla COM Microsoftu) i tak samo jest tylko dla C ++. Możesz zrobić COM Interop z C # i uciec od robienia tego w C #, ale prawdopodobnie będzie to zbyt trudne dla tego, co jest warte. Tak czy siak,

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

A dla akceleratorów, które są nowe w IE8, możesz to sprawdzić.

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

Zgadzam się, że dokumentacja jest okropna, a interfejsy API są dość przestarzałe. Nadal mam nadzieję, że to pomoże.

EDYCJA: Chyba mogę tu rzucić ostatnie źródło informacji. Przeglądałem notatki z przeszłości, kiedy pracowałem nad BHO. I to jest artykuł, od którego zacząłem. Jest trochę stary, ale ma dobre wyjaśnienie interfejsów ATL, których będziesz używać podczas pracy z IE BHO (na przykład IObjectWithSite). Myślę, że jest to dość dobrze wyjaśnione i bardzo mi wtedy pomogło. http://msdn.microsoft.com/en-us/library/bb250436.aspx Sprawdziłem również przykład opublikowany przez GregC. Działa z co najmniej IE8 i jest kompatybilny z VS 2010, więc jeśli chcesz zrobić C #, możesz zacząć tam i spojrzeć na książkę Jona Skeeta. (C # w szczegółach 2. edycja) Rozdział 13 zawiera sporo informacji na temat nowych funkcji w C # 4, których można użyć, aby poprawić interakcję z COM. (Nadal polecam zrobienie dodatku w C ++)

cloudraven
źródło
6

Opracowywanie BHO w języku C # jest bolesne. Wymaga wielu złośliwych kodów COM i wywołań p / invoke.

Mam głównie zakończeniu C # BHO tutaj , które mogą swobodnie korzystać źródło na cokolwiek chcesz. Mówię „głównie” , ponieważ nigdy nie wymyśliłem, jak zapisać appdata w trybie chronionym IE .

BlueRaja - Danny Pflughoeft
źródło
4
C # 4.0 może być lepszy pod tym względem, ponieważ COM Interop jest znacznie ulepszony.
Robert Harvey
@Robert: Naprawdę? Nie miałem pojęcia ... jakie są różnice?
user541686 16.0411
@Mehrdad: Możesz poznać różnice tutaj: devx.com/dotnet/Article/42590/1954 . Aby uzyskać bardziej dogłębną dyskusję, zobacz przemówienie Andersa Hejlsberga „The Future of C #” tutaj: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey
1
@Robert @Mehrdad: Nie bardzo. To nie interakcja COM jest nieprzyjemna (pod tym względem) , rozwija i rejestruje moduł COM, w którym nowe funkcje C # 4.0 nie pomagają.
BlueRaja - Danny Pflughoeft,
4

Od lat pracuję nad kontrolką przeglądarki internetowej IE, a w ich trakcie pojawia się jedna nazwa z pomocnymi postami: Igor Tandetnik

Gdybym opracowywał rozszerzenie, kierowałbym reklamy na BHO i zaczynałem wyszukiwanie w:

BHO Igor Tandetnik

LUB

Obiekt pomocnika przeglądarki Igor Tandetnik

Jego posty są często bardzo szczegółowe i wie, o czym mówi.

W programowaniu COM i ATL znajdziesz się do własnych uszu. Przykładowy przewodnik znajduje się na stronie: http://msdn.microsoft.com/en-us/library/ms976373.aspx

Lynn Crumbling
źródło
Największą wadą używania C # (w tym kierunku zmierza większość innych plakatów) jest to, że będzie przechodził przez różnego rodzaju dodatkowe warstwy, z obejściem i łatkami dla kodu, który byłby natywny dla C ++.
Lynn Crumbling
3

Jeśli nie próbujesz wymyślić koła na nowo, możesz wypróbować Add In Express dla IE . Użyłem tego produktu do VSTO i jest całkiem niezły. Mają też pomocne forum i szybkie wsparcie.

Sujay Ghosh
źródło
3

Jest oczywiście rozwiązany, ale innym użytkownikom poleciłbym framework SpicIE . Na tej podstawie stworzyłem własne rozszerzenie. Obsługuje tylko Internet Explorer 7/8 oficjalnie, ale przetestowałem go na Internet Explorerze 6-10 (od Windows XP do Windows 8 Consumer Preview) i działa dobrze . Niestety w najnowszej wersji pojawiły się błędy, więc musiałem je naprawić i stworzyć własną wersję: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251

Pěna
źródło
0

Gorąco polecam wam ten post Pavla Zolnikova opublikowany w 2002 roku!

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

Opiera się na wykorzystaniu obiektów Band i jest kompilowany przy użyciu .Net 2.0. Kod źródłowy jest dostępny, otwiera się i dobrze się kompiluje z Visual Studio 2013. Jak czytacie w komentarzach do postów, działa on doskonale dla IE 11 oraz Windows 7 i Windows 10. Działa doskonale dla mnie w Windows 7 + SP1 i IE 11 Ciesz się!

Marc Charmois
źródło
Lubimy, aby odpowiedzi były samodzielne w StackOverflow. Cały ten post naprawdę mówi mi: „użyj obiektów Band i .Net 2.0”. Czy możesz podać tutaj przykładowy kod, aby pokazać, jak można to zrobić?
Teepeemm
0

Pytanie pochodzi z 2013 roku, teraz jest 2020, ale może być pomocne dla przyszłych gości.

Próbowałem zaimplementować odpowiedź @Miguela Angelo, ale na początku nie zadziałało.

Nadal istnieją pewne ustawienia, które należy zdefiniować.

w przeglądarce Internet Explorer (używam IE-11) przejdź do Tools-->Internet Options-->Advanced: wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Zobacz także to pytanie SO i ten przykład z github

Nehorai
źródło
-2

wprowadź opis zdjęcia tutaj

Na karcie Zdarzenia kompilacji ustaw wiersz polecenia Zdarzenia po kompilacji na: (x64) znajduje się poniżej

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

Chcę zakładkę Build Events, ustaw wiersz poleceń Zdarzenia po kompilacji na (32-bitowy system operacyjny)

"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)"
użytkownik2564356
źródło