Come iniziare a sviluppare le estensioni di Internet Explorer?


207

Qualcuno qui ha esperienza con / nello sviluppo di estensioni IE che possono condividere le loro conoscenze? Ciò include esempi di codice, o collegamenti a quelli validi, o documentazione sul processo o altro.

Voglio davvero farlo, ma sto colpendo un muro gigante con documentazione scadente, codice scadente / esempio di codice / mancanza di ciò. Qualsiasi aiuto / risorse che potresti offrire sarebbe molto apprezzato.

In particolare, vorrei iniziare con come ottenere / manipolare il DOM dall'interno di un'estensione IE.

MODIFICA, ancora più dettagli:

Idealmente, vorrei piantare un pulsante della barra degli strumenti che, quando viene cliccato, fa apparire un menu che contiene collegamenti a siti esterni. Vorrei anche accedere al DOM e piantare JavaScript nella pagina in base ad alcune condizioni.

Qual è il modo migliore per conservare le informazioni in un'estensione IE? In Firefox / Chrome / Browser più moderni, si utilizzawindow.localStorage , ma ovviamente con IE8 / IE7, questa non è un'opzione. Forse un DB SQLite o simile? Va bene supporre che .NET 4.0 verrà installato sul computer di un utente?

Non voglio usare Spice IE perché voglio costruirne uno compatibile anche con IE9. Ho aggiunto anche il tag C ++ a questa domanda, perché se è meglio crearne uno in C ++, posso farlo.


1
IMHO IE 9 ha ordini di grandezza migliori delle versioni precedenti. (Non che lascerò Chrome per IE ovviamente ... non ancora comunque.)
user541686

1
@Alex: che tipo di cose prevedi di implementare in IE, in modo che possiamo iniziare a scavare nella giusta direzione generale?
GregC,

@Alex: Per scomporre questo problema in parti gestibili, dovrei sapere quanto segue: possiamo supporre che l'utente finale eseguirà IE9 e sarà disposto a installare dotNET 4.0 runtime?
GregC,

Sono d'accordo con GregC. Alcune ulteriori informazioni aiuteranno qui. Stai pensando a qualcosa come una barra degli strumenti o forse qualcosa che preelaborerà ciò che l'utente sta navigando o qualcosa che si collegherà a un servizio di terze parti.
cloudraven

4
@Alex, dai un'occhiata a Crossrider . Renderà la tua vita molto più semplice.
shdev,

Risposte:


229

[AGGIORNAMENTO] Sto aggiornando questa risposta per funzionare con Internet Explorer 11 , in Windows 10 x64 con Visual Studio 2017 Community . La versione precedente di questa risposta (per Internet Explorer 8, in Windows 7 x64 e Visual Studio 2010) è in fondo a questa risposta.

Creazione di un componente aggiuntivo di Internet Explorer 11 funzionante

Sto usando Visual Studio 2017 Community , C # , .Net Framework 4.6.1 , quindi alcuni di questi passaggi potrebbero essere leggermente diversi per te.

È necessario aprire Visual Studio come amministratore per creare la soluzione, in modo che lo script post-build possa registrare il BHO (necessita dell'accesso al registro).

Inizia creando una libreria di classi. Ho chiamato il mio InternetExplorerExtension .

Aggiungi questi riferimenti al progetto:

  • Interop.SHDocVw: scheda COM / ricerca per "Microsoft Internet Controls"
  • Microsoft.mshtml: scheda Assembly / cerca "Microsoft.mshtml"

Nota: in qualche modo MSHTML non è stato registrato nel mio sistema, anche se ho trovato nella finestra Aggiungi riferimento. Ciò ha causato un errore durante la creazione:

Impossibile trovare l'assieme wrapper per la libreria dei tipi "MSHTML"

La correzione è disponibile all'indirizzo http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html In alternativa, è possibile eseguire questo script batch:

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

Creare i seguenti file:

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

e infine un modulo, che useremo per configurare le opzioni. In questo modulo posizionare a TextBoxe un Ok Button. Impostare il DialogResult del pulsante su Ok . Inserisci questo codice nel codice del modulo:

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

Nelle proprietà del progetto, procedi come segue:

  • Firmare l'assemblaggio con un tasto di scelta rapida;
  • Nella scheda Debug, impostare Avvia programma esterno suC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Nella scheda Debug, impostare Argomenti della riga di comando suhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Nella scheda Eventi di build, imposta la riga di comando Eventi post-build su:

    "% 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" / annulla la registrazione "$ (TargetDir) $ (TargetFileName)"
    
    "% windir% \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" "$ (TargetDir) $ (TargetFileName)"

Attenzione: anche se il mio computer è x64, ho usato il percorso di non-x64 gacutil.exee ha funzionato ... quello specifico per x64 è su:

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

64 bit IE Ha bisogno di BHO compilato a 64 bit e registrato a 64 bit. Anche se ho potuto eseguire il debug solo con IE11 a 32 bit, l'estensione registrata a 32 bit ha funzionato anche eseguendo IE11 a 64 bit.

Questa risposta sembra avere alcune informazioni aggiuntive a riguardo: https://stackoverflow.com/a/23004613/195417

Se è necessario, è possibile utilizzare il regasm a 64 bit:

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

Come funziona questo componente aggiuntivo

Non ho modificato il comportamento del componente aggiuntivo ... dai un'occhiata alla seguente sezione IE8 per la descrizione.


Risposta precedente per IE8

Amico ... è stato un sacco di lavoro! Ero così curioso di come farlo, che l'ho fatto da solo.

Prima di tutto ... il credito non è tutto mio. Questa è una raccolta di ciò che ho trovato su questi siti:

E, naturalmente, volevo che la mia risposta avesse le funzionalità che hai chiesto:

  • DOM traversal per trovare qualcosa;
  • un pulsante che mostra una finestra (nel mio caso l'installazione)
  • persistere nella configurazione (userò il registro per quello)
  • ed infine esegui javascript.

Lo descriverò passo dopo passo, come sono riuscito a farlo lavorando con Internet Explorer 8 , in Windows 7 x64 ... nota che non ho potuto testare in altre configurazioni. Spero che tu capisca =)

Creazione di un componente aggiuntivo di Internet Explorer 8 funzionante

Sto usando Visual Studio 2010 , C # 4 , .Net Framework 4 , quindi alcuni di questi passaggi potrebbero essere leggermente diversi per te.

Creato una biblioteca di classe. Ho chiamato il mio InternetExplorerExtension .

Aggiungi questi riferimenti al progetto:

  • Interop.SHDocVw
  • Microsoft.mshtml

Nota: questi riferimenti possono trovarsi in luoghi diversi in ciascun computer.

questo è ciò che contiene la mia sezione di riferimenti in 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" />

Crea i file nello stesso modo dei file IE11 aggiornati.

IEAddon.cs

È possibile rimuovere il commento dalle seguenti righe dalla versione 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

Come per la versione IE11.

e infine un modulo, che useremo per configurare le opzioni. In questo modulo posizionare a TextBoxe un Ok Button. Impostare il DialogResult del pulsante su Ok . Il codice è lo stesso per il componente aggiuntivo IE11.

Nelle proprietà del progetto, procedi come segue:

  • Firmare l'assemblaggio con un tasto di scelta rapida;
  • Nella scheda Debug, impostare Avvia programma esterno suC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Nella scheda Debug, impostare Argomenti della riga di comando suhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Nella scheda Eventi di build, imposta la riga di comando Eventi post-build su:

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

Attenzione: poiché il mio computer è x64, c'è un x64 specifico nel percorso dell'eseguibile di gacutil sulla mia macchina che potrebbe essere diverso sul tuo.

64 bit IE Ha bisogno di BHO compilato a 64 bit e registrato a 64 bit. Usa RegAsm.exe a 64 bit (in genere vive in C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Come funziona questo componente aggiuntivo

Attraversa tutto l'albero del DOM, sostituendo il testo, configurato mediante il pulsante, da solo con uno sfondo giallo. Se fai clic sui testi ingialliti, chiama una funzione javascript che è stata inserita dinamicamente nella pagina. La parola predefinita è "browser", in modo che corrisponda a molti di loro! MODIFICARE: dopo aver modificato la stringa da evidenziare, è necessario fare clic sulla casella URL e premere Invio ... F5 non funzionerà, penso che sia perché F5 è considerato come "navigazione" e richiederebbe di ascoltare l'evento di navigazione (può essere). Proverò a risolverlo più tardi.

Ora è tempo di andare. Sono molto stanco. Sentiti libero di fare domande ... forse non sarò in grado di rispondere da quando vado in viaggio ... tra 3 giorni sono tornato, ma proverò a venire qui nel frattempo.


2
Ciao, ho fatto esattamente ciò che è descritto nella risposta. Viene visualizzato il pulsante. Viene eseguita la funzione exec. Tuttavia, le funzioni SetSite e GetSite non vengono mai chiamate. Voglio essere in grado di conoscere l'URL della pagina in cui mi trovo. Non riesce a chiamare questi metodi per inizializzare il browser .. Per favore
aiutatemi

3
Ho provato a farlo su IE9 e: 1. Se il percorso del tuo progetto ha spazi: invece di $(TargetDir)$(TargetFileName)usare "$(TargetDir)$(TargetFileName)" 2. Se usi Visual Studio 2010 Express probabilmente (Io) non vedrai l' opzione Avvia programma esterno nella scheda Debug - I esegui semplicemente IE e vai all'URL fornito 3. Sembra che non funzioni su IE9 : posso aprire il modulo (Opzioni evidenziatore) ma non so come evidenziarlo
pinus.acer

8
Per il riferimento Interop.SHDocVw - invece è necessario aggiungere un riferimento COM a "Microsoft Internet Controls" e quindi "utilizzando SHDocVw;"
Eric Hartford,

8
"IE10 su x64 Windows 8 non caricherà il componente aggiuntivo all'avvio a meno che non si crei con architettura" Any CPU "e si registri utilizzando RegAsm.exe a 32 e 64 bit." è stata una modifica di qualcuno che è stato rifiutato.
Matsemann,

3
Si prega di consultare il follow-up: stackoverflow.com/questions/22953571/...

12

Un altro approccio interessante sarebbe quello di verificare:

http://www.crossrider.org

È un framework basato su JS con jquery che ti consente di sviluppare estensioni del browser per IE, FF e Chrome utilizzando un unico codice JS comune. Fondamentalmente il framework fa tutto il lavoro cattivo e ti rimane con la scrittura del codice delle applicazioni.


Sì, questa è davvero la strada da percorrere, oltre a evitare l'incubo che sta sviluppando un plugin in Visual Studio, significa che devi scrivere il tuo plugin una sola volta per tutti i browser. Significa anche non dover sviluppare in una macchina virtuale se sei un utente mac.
opsb,

11

Lo stato delle estensioni di IE è in realtà piuttosto triste. Hai il vecchio modello di IE5 Browser Helper Object (sì, quei famigerati BHO che a tutti piaceva bloccare nel corso della giornata), barre degli strumenti e i nuovi acceleratori per IE. Anche allora, la compatibilità a volte si romperà. Ero solito mantenere un'estensione per IE6 che si è rotta con IE7, quindi ci sono alcune cose che sono cambiate. Per la maggior parte, per quanto ne so (non tocco i BHO da anni) è ancora necessario codificarli utilizzando Active Template Libraries (un po 'come un STL per COM di Microsoft) e come tale è solo per C ++. Potresti fare l'interoperabilità COM con C # e cavartela con C #, ma probabilmente sarà troppo difficile per quello che vale. Comunque,

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

E per gli acceleratori che sono nuovi in ​​IE8 puoi controllare questo.

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

Sono d'accordo che la documentazione è terribile e le API sono abbastanza obsolete. Spero ancora che questo aiuti.

EDIT: immagino di poter gettare qui un'ultima fonte di informazioni. Stavo guardando attraverso le mie note di schiena quando stavo lavorando su BHO. E questo è l'articolo che mi ha fatto iniziare con loro. È un po 'vecchio, ma ha una buona spiegazione delle interfacce ATL che userete quando lavorate con IE BHO (IObjectWithSite per esempio). Penso che sia abbastanza ben spiegato e mi ha aiutato molto allora. http://msdn.microsoft.com/en-us/library/bb250436.aspx Ho anche controllato l'esempio pubblicato da GregC. Funziona con almeno IE8 ed è compatibile con VS 2010, quindi se vuoi fare C # puoi iniziare lì e dare un'occhiata al Jon Skeet's Book. (C # in Depth 2nd edition) Il capitolo 13 contiene molte informazioni sulle nuove funzionalità di C # 4 che è possibile utilizzare per rendere più piacevole l'interazione con COM. (Ti consiglierei comunque di fare il tuo componente aggiuntivo in C ++)


6

Lo sviluppo di C # BHO è una seccatura. Implica un sacco di codice COM e chiamate p / invoke.

Ho un BHO C # per lo più finito qui , che sei libero di usare la fonte per quello che vuoi. Dico "principalmente" , perché non ho mai capito come salvare appdata in IE Protected Mode .


4
C # 4.0 potrebbe essere migliore in questo senso, poiché l'interoperabilità COM è molto migliorata.
Robert Harvey,

@Robert: Davvero? Non avevo idea ... quali sono le differenze?
user541686,

@Mehrdad: puoi avere un assaggio delle differenze qui: devx.com/dotnet/Article/42590/1954 . Per una discussione più approfondita, vedi il discorso di Anders Hejlsberg, "Il futuro di C #", qui: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey,

1
@Robert @Mehrdad: Non proprio. Non è l'interoperabilità COM ad essere pericolosa (a questo proposito) , sta sviluppando e registrando un modulo COM, con cui le nuove funzionalità di C # 4.0 non aiutano.
BlueRaja - Danny Pflughoeft,

4

Lavoro con il controllo del browser web di IE ormai da anni e, nel corso di essi, un nome viene ripetutamente ripetutamente con utili post: Igor Tandetnik

Se stavo sviluppando un'estensione, sceglierei come target un BHO e inizierei a cercare su Google:

BHO Igor Tandetnik

O

Browser Helper Object Igor Tandetnik

I suoi post sono spesso molto dettagliati e sa di cosa sta parlando.

Ti troverai nelle tue orecchie nella programmazione COM e ATL. Per una procedura dettagliata di esempio, controlla: http://msdn.microsoft.com/en-us/library/ms976373.aspx


Il più grande svantaggio dell'uso di C # (che è la direzione che la maggior parte degli altri poster sta andando) è che passerà attraverso tutti i tipi di livelli extra, con soluzioni alternative e patch per il codice che sarebbe nativo di C ++.
Lynn che si sbriciola il



3

Ovviamente è risolto, ma per gli altri utenti, consiglierei il framework SpicIE . Ho creato la mia estensione basata su di essa. Supporta solo Internet Explorer 7/8 ufficialmente, ma l'ho provato su Internet Explorer 6-10 (da Windows XP a Windows 8 Consumer Preview) e funziona benissimo . Purtroppo ci sono stati alcuni bug nell'ultima versione, quindi ho dovuto risolverli e ho creato la mia versione: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251


0

Vi consiglio caldamente questo post di Pavel Zolnikov pubblicato nel 2002!

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

Si basa sull'uso di oggetti Band e viene compilato utilizzando .Net 2.0. Il codice sorgente viene fornito, aperto e compilato bene con Visual Studio 2013. Come leggerai nei commenti post, funziona perfettamente per IE 11 e Windows 7 e Windows 10. Ha funzionato perfettamente per me su Windows 7 + SP1 e IE 11 Divertiti!


Ci piace che le risposte siano autonome su StackOverflow. Tutto questo post mi dice davvero "usa oggetti Band e .Net 2.0". Potresti includere qui un codice di esempio per mostrare come potrebbe essere fatto?
Teepeemm,

0

La domanda è del 2013, ora è il 2020, ma può essere utile per i futuri visitatori.

Ho cercato di implementare la risposta di @Miguel Angelo, all'inizio non ha funzionato.

Ci sono ancora alcune impostazioni da definire.

su Internet Explorer (sto usando IE-11) vai a Tools-->Internet Options-->Advanced: inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Vedi anche questa domanda SO e questo esempio da Github


-2

inserisci qui la descrizione dell'immagine

Nella scheda Eventi di build, imposta la riga di comando Eventi post-build su: (x64) è elencato di seguito

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

Voglio la scheda Eventi di build, impostare la riga di comando Eventi post-build su (sistema operativo a 32 bit)

"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)"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.