Wie fange ich mit der Entwicklung von Internet Explorer-Erweiterungen an?


207

Hat hier jemand Erfahrung mit / in der Entwicklung von IE-Erweiterungen, die sein Wissen teilen können? Dies würde Codebeispiele oder Links zu guten oder Dokumentationen über den Prozess oder irgendetwas beinhalten.

Ich möchte das wirklich tun, aber ich stoße auf eine riesige Wand mit mieser Dokumentation, miesem Code / Beispielcode / Mangel daran. Jede Hilfe / Ressourcen, die Sie anbieten könnten, wäre sehr dankbar.

Insbesondere möchte ich damit beginnen, wie Sie über eine IE-Erweiterung auf das DOM zugreifen bzw. es bearbeiten können.

EDIT, noch mehr Details:

Im Idealfall möchte ich eine Symbolleistenschaltfläche einfügen, die beim Klicken ein Menü mit Links zu externen Websites öffnet. Ich möchte auch auf das DOM zugreifen und JavaScript auf der Seite abhängig von einigen Bedingungen pflanzen.

Was ist der beste Weg, um Informationen in einer IE-Erweiterung beizubehalten? In Firefox / Chrome / den meisten modernen Browsern verwenden Sie window.localStorage, aber mit IE8 / IE7 ist dies natürlich keine Option. Vielleicht eine SQLite-Datenbank oder so? Es ist in Ordnung anzunehmen, dass .NET 4.0 auf dem Computer eines Benutzers installiert wird.

Ich möchte Spice IE nicht verwenden, da ich einen erstellen möchte, der auch mit IE9 kompatibel ist. Ich habe das C ++ - Tag auch zu dieser Frage hinzugefügt, denn wenn es besser ist, eines in C ++ zu erstellen, kann ich das tun.


1
IMHO IE 9 ist um Größenordnungen besser als die Vorgängerversionen. (Nicht, dass ich Chrome für IE verlassen würde ... natürlich noch nicht.)
user541686

1
@Alex: Welche Art von Dingen stellen Sie sich vor, um sie im IE zu implementieren, damit wir in die richtige allgemeine Richtung graben können?
GregC

@Alex: Um dieses Problem in überschaubare Teile zu zerlegen, müsste ich Folgendes wissen: Können wir davon ausgehen, dass der Endbenutzer IE9 ausführt und bereit ist, die dotNET 4.0-Laufzeit zu installieren?
GregC

Ich stimme GregC zu. Weitere Informationen helfen hier. Denken Sie an etwas wie eine Symbolleiste oder an etwas, das vorab verarbeitet, was der Benutzer durchsucht, oder an etwas, das eine Verbindung zu einem Dienst eines Drittanbieters herstellt.
Cloudraven

4
@Alex, schau dir Crossrider an . Es wird Ihr Leben viel einfacher machen.
Shdev

Antworten:


229

[UPDATE] Ich aktualisiere diese Antwort, um mit Internet Explorer 11 in Windows 10 x64 mit Visual Studio 2017 Community zu arbeiten . Die vorherige Version dieser Antwort (für Internet Explorer 8 in Windows 7 x64 und Visual Studio 2010) befindet sich am Ende dieser Antwort.

Erstellen eines funktionierenden Internet Explorer 11-Add-ons

Ich verwende Visual Studio 2017 Community , C # , .Net Framework 4.6.1 , daher können einige dieser Schritte für Sie etwas anders sein.

Sie müssen Visual Studio als Administrator öffnen , um die Lösung zu erstellen, damit das Post-Build-Skript das BHO registrieren kann (Registrierungszugriff erforderlich).

Erstellen Sie zunächst eine Klassenbibliothek. Ich habe meine InternetExplorerExtension angerufen .

Fügen Sie dem Projekt diese Verweise hinzu:

  • Interop.SHDocVw: Registerkarte COM / Suche nach "Microsoft Internet Controls"
  • Microsoft.mshtml: Registerkarte / Suche nach Baugruppen "Microsoft.mshtml"

Hinweis: Irgendwie wurde MSHTML nicht in meinem System registriert, obwohl ich es im Fenster Referenz hinzufügen finden konnte. Dies verursachte einen Fehler beim Erstellen:

Wrapper-Assembly für Typbibliothek "MSHTML" kann nicht gefunden werden

Das Update finden Sie unter http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html . Sie können auch dieses Batch-Skript ausführen:

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

Erstellen Sie die folgenden Dateien:

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

und schließlich ein Formular, mit dem wir die Optionen konfigurieren. In dieser Form platzieren Sie ein TextBoxund ein Ok Button. Stellen Sie die Dialogresult der Schaltfläche Ok . Fügen Sie diesen Code in den Formularcode ein:

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

Gehen Sie in den Projekteigenschaften wie folgt vor:

  • Unterschreiben Sie die Versammlung mit einem starken Schlüssel.
  • Setzen Sie auf der Registerkarte Debuggen auf Externes Programm starten aufC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Setzen Sie auf der Registerkarte Debuggen Befehlszeilenargumente aufhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Setzen Sie auf der Registerkarte Build -Ereignisse die Befehlszeile Post-Build-Ereignisse auf:

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

Achtung: Obwohl mein Computer x64 ist, habe ich den Pfad des Nicht-x64 verwendet gacutil.exeund es hat funktioniert ... der für x64 spezifische ist:

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

64- Bit- IE Benötigt 64-Bit-kompiliertes und 64-Bit-registriertes BHO. Obwohl ich nur mit 32-Bit-IE11 debuggen konnte, funktionierte die registrierte 32-Bit-Erweiterung auch mit 64-Bit-IE11.

Diese Antwort scheint einige zusätzliche Informationen zu enthalten: https://stackoverflow.com/a/23004613/195417

Wenn nötig, können Sie das 64-Bit-Regime verwenden:

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

Wie dieses Add-On funktioniert

Ich habe das Verhalten des Add-Ons nicht geändert. Eine Beschreibung finden Sie im Abschnitt IE8 unten.


## Vorherige Antwort für IE8

Mann ... das war viel Arbeit! Ich war so neugierig, wie ich das machen sollte, dass ich es selbst gemacht habe.

Zuallererst ... Kredit ist nicht alles von mir. Dies ist eine Zusammenstellung dessen, was ich auf diesen Websites gefunden habe:

Und natürlich wollte ich, dass meine Antwort die Funktionen enthält, die Sie gefragt haben:

  • DOM-Durchquerung, um etwas zu finden;
  • eine Schaltfläche, die ein Fenster anzeigt (in meinem Fall zum Einrichten)
  • Behalte die Konfiguration bei (ich werde dafür die Registrierung verwenden)
  • und schließlich Javascript ausführen.

Ich werde es Schritt für Schritt beschreiben, wie ich es mit Internet Explorer 8 in Windows 7 x64 geschafft habe ... Beachten Sie, dass ich in anderen Konfigurationen nicht testen konnte. Hoffe du verstehst =)

Erstellen eines funktionierenden Internet Explorer 8-Add-ons

Ich verwende Visual Studio 2010 , C # 4 , .Net Framework 4 , daher können einige dieser Schritte für Sie etwas anders sein.

Erstellt eine Klassenbibliothek. Ich habe meine InternetExplorerExtension angerufen .

Fügen Sie dem Projekt diese Verweise hinzu:

  • Interop.SHDocVw
  • Microsoft.mshtml

Hinweis: Diese Referenzen befinden sich möglicherweise an verschiedenen Stellen in jedem Computer.

Dies ist, was mein Referenzabschnitt in csproj enthält:

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

Erstellen Sie die Dateien auf die gleiche Weise wie die aktualisierten IE11-Dateien.

IEAddon.cs

Sie können die folgenden Zeilen aus der IE11-Version auskommentieren:

...
// @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

Gleich wie IE11-Version.

und schließlich ein Formular, mit dem wir die Optionen konfigurieren. In dieser Form platzieren Sie ein TextBoxund ein Ok Button. Stellen Sie die Dialogresult der Schaltfläche Ok . Der Code ist der gleiche für das IE11-Addon.

Gehen Sie in den Projekteigenschaften wie folgt vor:

  • Unterschreiben Sie die Versammlung mit einem starken Schlüssel.
  • Setzen Sie auf der Registerkarte Debuggen auf Externes Programm starten aufC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Setzen Sie auf der Registerkarte Debuggen Befehlszeilenargumente aufhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Setzen Sie auf der Registerkarte Build -Ereignisse die Befehlszeile Post-Build-Ereignisse auf:

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

Achtung: Da mein Computer x64 ist, befindet sich im Pfad der ausführbaren Datei von gacutil auf meinem Computer ein bestimmtes x64, das auf Ihrem Computer möglicherweise anders ist.

64- Bit- IE Benötigt 64-Bit-kompiliertes und 64-Bit-registriertes BHO. Verwenden Sie 64-Bit-RegAsm.exe (normalerweise in C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe).

Wie dieses Add-On funktioniert

Es durchläuft den gesamten DOM-Baum und ersetzt den mit der Schaltfläche konfigurierten Text durch einen gelben Hintergrund. Wenn Sie auf die vergilbten Texte klicken, wird eine Javascript-Funktion aufgerufen, die dynamisch auf der Seite eingefügt wurde. Das Standardwort ist "Browser", so dass es mit vielen von ihnen übereinstimmt! BEARBEITEN: Nachdem Sie die hervorzuhebende Zeichenfolge geändert haben, müssen Sie auf das URL-Feld klicken und die Eingabetaste drücken. F5 funktioniert nicht. Ich denke, dies liegt daran, dass F5 als 'Navigation' betrachtet wird und das Navigationsereignis abgehört werden muss (vielleicht). Ich werde versuchen, das später zu beheben.

Jetzt ist es Zeit zu gehen. Ich bin sehr müde. Fühlen Sie sich frei, Fragen zu stellen ... vielleicht kann ich nicht antworten, da ich auf eine Reise gehe ... in 3 Tagen bin ich zurück, aber ich werde versuchen, in der Zwischenzeit hierher zu kommen.


2
Hallo, ich habe genau das getan, was in der Antwort beschrieben ist. Die Schaltfläche wird angezeigt. Die Ausführungsfunktion wird ausgeführt. SetSite- und GetSite-Funktionen werden jedoch niemals aufgerufen. Ich möchte die URL der Seite kennen, auf der ich mich befinde. Es ist nicht möglich, diese Methoden aufzurufen, um den Browser zu initialisieren. Bitte helfen Sie
mustafabar

3
Ich habe versucht , dies auf IE9 zu tun und: 1. Wenn Ihr Projektpfad hat Plätze: statt $(TargetDir)$(TargetFileName)Verwendung "$(TargetDir)$(TargetFileName)" 2. Wenn Sie Visual Studio 2010 Express verwenden Sie wahrscheinlich (ich) nicht sehen , die Externe Programm Option in Debug Tab - I Führen Sie einfach den IE aus und navigieren Sie zur angegebenen URL 3. Es scheint nicht mit IE9 zu funktionieren - ich kann das Formular öffnen (Textmarker-Optionen), aber ich weiß nicht, wie ich den Text
hervorheben soll

8
Für die Interop.SHDocVw-Referenz sollten Sie stattdessen eine COM-Referenz zu "Microsoft Internet Controls" und dann "using SHDocVw" hinzufügen.
Eric Hartford

8
"IE10 unter x64 Windows 8 lädt Ihr Add-On beim Start nur, wenn Sie mit" Any CPU "-Architektur erstellen und sich mit 32- und 64-Bit-RegAsm.exe registrieren." war eine Bearbeitung von jemandem, der abgelehnt wurde.
Matsemann

3
Bitte sehen Sie das Follow-up: stackoverflow.com/questions/22953571/…

12

Ein weiterer cooler Ansatz wäre das Auschecken:

http://www.crossrider.org

Es ist ein auf JS basierendes Framework mit jquery, mit dem Sie Browsererweiterungen für IE, FF und Chrome mit einem einzigen gemeinsamen JS-Code entwickeln können. Grundsätzlich erledigt das Framework die ganze böse Arbeit und Sie müssen nur noch Ihren Anwendungscode schreiben.


Ja, dies ist wirklich der richtige Weg. Um den Albtraum zu vermeiden, der ein Plugin in Visual Studio entwickelt, müssen Sie Ihr Plugin nur einmal für alle Browser schreiben. Es bedeutet auch, dass Sie sich nicht in einer virtuellen Maschine entwickeln müssen, wenn Sie ein Mac-Benutzer sind.
opsb

11

Der Zustand für IE-Erweiterungen ist eigentlich ziemlich traurig. Sie haben das alte Modell des IE5-Browser-Hilfsobjekts (ja, diese berüchtigten BHOs, die früher alle gerne blockierten), Symbolleisten und die neuen Beschleuniger für den IE. Selbst dann wird die Kompatibilität manchmal unterbrochen. Ich habe eine Erweiterung für IE6 beibehalten, die mit IE7 kaputt gegangen ist, daher haben sich einige Dinge geändert. Soweit ich weiß (ich habe BHOs ​​seit Jahren nicht mehr berührt), müssen Sie sie größtenteils noch mit Active Template Libraries (ähnlich einer STL für Microsoft COM) codieren, und dies gilt auch nur für C ++. Sie könnten COM Interop mit C # machen und es in C # schaffen, aber es wird wahrscheinlich zu schwer für das, was es wert ist. Wie auch immer,

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

Und für die Beschleuniger, die neu in IE8 sind, können Sie diese überprüfen.

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

Ich bin damit einverstanden, dass die Dokumentation schrecklich ist und die APIs ziemlich veraltet sind. Trotzdem hoffe ich, dass dies hilft.

EDIT: Ich denke, ich kann hier eine letzte Informationsquelle werfen. Ich habe meine Notizen durchgesehen, als ich an BHOs ​​gearbeitet habe. Und das ist der Artikel, mit dem ich angefangen habe. Es ist ein bisschen alt, hat aber eine gute Erklärung der ATL-Schnittstellen, die Sie bei der Arbeit mit IE-BHOs (z. B. IObjectWithSite) verwenden werden. Ich denke, es ist ziemlich gut erklärt und hat mir damals sehr geholfen. http://msdn.microsoft.com/en-us/library/bb250436.aspx Ich habe auch das Beispiel überprüft, das GregC gepostet hat. Es funktioniert mit mindestens IE8 und ist mit VS 2010 kompatibel. Wenn Sie also C # ausführen möchten, können Sie dort loslegen und sich Jon Skeets Buch ansehen. (C # in Depth 2nd Edition) Kapitel 13 enthält zahlreiche Informationen zu den neuen Funktionen in C # 4, mit denen Sie die Interaktion mit COM verbessern können. (Ich würde dir trotzdem empfehlen, dein Addin in C ++ zu machen)


6

Die Entwicklung von C # -BHOs ist ein Ärgernis. Es beinhaltet eine Menge icky COM-Code und p / invoke-Aufrufe.

Ich habe eine meist fertig C # BHO hier , den Sie kostenlos zu benutzen sind die Quelle für alles , was Sie wollen. Ich sage "meistens" , weil ich nie herausgefunden habe, wie man App-Daten im IE-geschützten Modus speichert .


4
C # 4.0 könnte in dieser Hinsicht besser sein, da COM Interop stark verbessert wurde.
Robert Harvey

@ Robert: Wirklich? Ich hatte keine Ahnung ... was sind die Unterschiede?
user541686

@Mehrdad: Hier können Sie einen Eindruck von den Unterschieden bekommen: devx.com/dotnet/Article/42590/1954 . Eine ausführlichere Diskussion finden Sie in Anders Hejlsbergs Vortrag "Die Zukunft von C #" hier: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey

1
@ Robert @ Mehrdad: Nicht wirklich. Es ist nicht das COM-Interop, das (in dieser Hinsicht) schwierig ist , es entwickelt und registriert ein COM-Modul, bei dem die neuen C # 4.0-Funktionen nicht helfen.
BlueRaja - Danny Pflughoeft

4

Ich arbeite seit Jahren mit der Webbrowser-Steuerung von IE, und im Laufe der Zeit taucht immer wieder ein Name mit hilfreichen Beiträgen auf: Igor Tandetnik

Wenn ich eine Erweiterung entwickeln würde, würde ich ein BHO ins Visier nehmen und anfangen zu googeln nach:

BHO Igor Tandetnik

ODER

Browser-Hilfsobjekt Igor Tandetnik

Seine Beiträge sind oft sehr detailliert und er weiß, wovon er spricht.

Sie werden sich in der COM- und ATL-Programmierung bis an die Ohren wiederfinden. Eine exemplarische Vorgehensweise finden Sie unter: http://msdn.microsoft.com/en-us/library/ms976373.aspx


Der größte Nachteil bei der Verwendung von C # (dies ist die Richtung, in die die meisten anderen Poster gehen) ist, dass alle möglichen zusätzlichen Ebenen durchlaufen werden, mit Problemumgehung und Patches für Code, der in C ++ nativ wäre.
Lynn Crumbling



3

Es ist offensichtlich gelöst, aber für die anderen Benutzer würde ich das SpicIE-Framework empfehlen . Ich habe darauf basierend meine eigene Erweiterung erstellt. Es unterstützt nur offiziell Internet Explorer 7/8, aber ich habe das unter Internet Explorer 6-10 (von Windows XP bis Windows 8 Consumer Preview) getestet und es funktioniert einwandfrei . Leider gab es in der neuesten Version einige Fehler, daher musste ich sie beheben und meine eigene Version erstellen : http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251


0

Ich empfehle Ihnen wärmstens diesen Beitrag von Pavel Zolnikov, der 2002 veröffentlicht wurde!

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

Es basiert auf der Verwendung von Bandobjekten und wird mit .Net 2.0 kompiliert. Der Quellcode wird bereitgestellt und wird mit Visual Studio 2013 gut geöffnet und kompiliert. Wie Sie in den Kommentaren lesen werden, funktioniert er perfekt für IE 11 und Windows 7 und Windows 10. Für Windows 7 + SP1 und IE hat er perfekt funktioniert 11 Viel Spaß!


Wir möchten, dass Antworten in StackOverflow in sich geschlossen sind. Alles, was dieser Beitrag mir wirklich sagt, ist "Bandobjekte und .Net 2.0 verwenden". Könnten Sie hier einen Beispielcode einfügen, um zu zeigen, wie dies getan werden kann?
Teepeemm

0

Die Frage stammt aus dem Jahr 2013, jetzt ist es 2020, aber sie kann für zukünftige Besucher hilfreich sein.

Ich habe versucht, die Antwort von @Miguel Angelo umzusetzen, es hat am Anfang nicht funktioniert.

Es gibt noch einige Einstellungen, die Sie definieren.

Im Internet Explorer (ich verwende IE-11) gehen Sie zu Tools-->Internet Options-->Advanced: Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Siehe auch diese SO-Frage und dieses Beispiel von Github


-2

Geben Sie hier die Bildbeschreibung ein

Setzen Sie auf der Registerkarte Build-Ereignisse die Befehlszeile Post-Build-Ereignisse auf: (x64) ist unten aufgeführt

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

Ich möchte, dass auf der Registerkarte Build Events die Befehlszeile Post-Build Events auf (32-Bit-Betriebssystem) gesetzt wird.

"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)"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.