Comment commencer à développer des extensions Internet Explorer?


207

Quelqu'un ici a-t-il de l'expérience avec / dans le développement d'extensions IE qui peuvent partager leurs connaissances? Cela comprendrait des exemples de code, ou des liens vers de bons, ou de la documentation sur le processus, ou quoi que ce soit.

Je veux vraiment le faire, mais je frappe un mur géant avec une documentation moche, un code moche / un exemple de code / son absence. Toute aide / ressources que vous pourriez offrir serait grandement appréciée.

Plus précisément, je voudrais commencer par savoir comment accéder au / manipuler le DOM à partir d'une extension IE.

EDIT, encore plus de détails:

Idéalement, je voudrais planter un bouton de barre d'outils qui, lorsque vous cliquez dessus, fait apparaître un menu contenant des liens vers des sites externes. Je voudrais également accéder au DOM et planter du JavaScript sur la page en fonction de certaines conditions.

Quelle est la meilleure façon de conserver les informations dans une extension IE? Dans Firefox / Chrome / La plupart des navigateurs modernes, vous utilisez window.localStorage, mais évidemment avec IE8 / IE7, ce n'est pas une option. Peut-être une base de données SQLite ou autre? Est-il correct de supposer que .NET 4.0 sera installé sur l'ordinateur d'un utilisateur?

Je ne veux pas utiliser Spice IE car je veux en créer un qui est également compatible avec IE9. J'ai également ajouté la balise C ++ à cette question, car s'il est préférable d'en créer une en C ++, je peux le faire.


1
IMHO IE 9 est de l'ordre de grandeur mieux que les versions précédentes. (Pas que je laisse Chrome pour IE bien sûr ... pas encore de toute façon.)
user541686

1
@Alex: quel genre de choses envisagez-vous d'implémenter dans IE, afin que nous puissions commencer à creuser dans la bonne direction générale?
GregC

@Alex: Afin de décomposer ce problème en éléments gérables, j'aurais besoin de savoir ce qui suit: pouvons-nous supposer que l'utilisateur final exécutera IE9 et sera prêt à installer le runtime dotNET 4.0?
GregC

Je suis d'accord avec GregC. Quelques informations supplémentaires vous aideront ici. Pensez-vous à quelque chose comme une barre d'outils, ou peut-être quelque chose qui pré-traitera ce que l'utilisateur navigue ou quelque chose qui se connectera à un service tiers.
cloudraven

4
@Alex, jetez un œil à Crossrider . Cela vous facilitera la vie.
shdev

Réponses:


229

[MISE À JOUR] Je mets à jour cette réponse pour fonctionner avec Internet Explorer 11 , dans Windows 10 x64 avec la communauté Visual Studio 2017 . La version précédente de cette réponse (pour Internet Explorer 8, dans Windows 7 x64 et Visual Studio 2010) se trouve au bas de cette réponse.

Création d'un module complémentaire Internet Explorer 11 fonctionnel

J'utilise Visual Studio 2017 Community , C # , .Net Framework 4.6.1 , donc certaines de ces étapes peuvent être légèrement différentes pour vous.

Vous devez ouvrir Visual Studio en tant qu'administrateur pour créer la solution, afin que le script post-génération puisse enregistrer le BHO (nécessite un accès au registre).

Commencez par créer une bibliothèque de classes. J'ai appelé le mien InternetExplorerExtension .

Ajoutez ces références au projet:

  • Interop.SHDocVw: onglet COM / recherche "Microsoft Internet Controls"
  • Microsoft.mshtml: onglet Assemblages / recherche "Microsoft.mshtml"

Remarque: MSHTML n'était pas enregistré dans mon système, même si je pouvais le trouver dans la fenêtre Ajouter une référence. Cela a provoqué une erreur lors de la construction:

Impossible de trouver l'assembly d'encapsuleur pour la bibliothèque de types "MSHTML"

Le correctif peut être trouvé à http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html Ou, vous pouvez exécuter ce script de commandes:

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

Créez les fichiers suivants:

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

et enfin un formulaire, que nous utiliserons pour configurer les options. Dans ce formulaire, placez un TextBoxet un Ok Button. Réglez DialogResult du bouton sur Ok . Placez ce code dans le code du formulaire:

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

Dans les propriétés du projet, procédez comme suit:

  • Signez l'assemblage avec une touche forte;
  • Dans l'onglet Déboguer, définissez Démarrer le programme externe surC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Dans l'onglet Déboguer, définissez Arguments de ligne de commande surhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Dans l'onglet Générer des événements, définissez la ligne de commande des événements post-génération sur:

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

Attention: même si mon ordinateur est x64, j'ai utilisé le chemin du non-x64 gacutil.exeet cela a fonctionné ... celui spécifique pour x64 est à:

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

IE 64 bits a besoin de BHO compilé en 64 bits et enregistré en 64 bits. Bien que je ne pouvais que déboguer en utilisant 32 bits IE11, l'extension enregistrée 32 bits fonctionnait également en exécutant 64 bits IE11.

Cette réponse semble avoir quelques informations supplémentaires à ce sujet: https://stackoverflow.com/a/23004613/195417

Si vous en avez besoin, vous pouvez utiliser le regasm 64 bits:

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

Comment fonctionne ce module complémentaire

Je n'ai pas changé le comportement du module complémentaire ... jetez un œil à la section IE8 ci-dessous pour la description.


## Réponse précédente pour IE8

Mec ... ça a été beaucoup de travail! J'étais tellement curieux de savoir comment faire cela, que je l'ai fait moi-même.

Tout d'abord ... le crédit n'est pas tout à moi. Voici une compilation de ce que j'ai trouvé sur ces sites:

Et bien sûr, je voulais que ma réponse ait les fonctionnalités que vous avez demandées:

  • Traversée DOM pour trouver quelque chose;
  • un bouton qui affiche une fenêtre (dans mon cas pour configurer)
  • conserver la configuration (j'utiliserai le registre pour cela)
  • et enfin exécuter javascript.

Je vais le décrire étape par étape, comment j'ai réussi à le faire en travaillant avec Internet Explorer 8 , sous Windows 7 x64 ... notez que je n'ai pas pu tester dans d'autres configurations. J'espère que vous comprenez =)

Création d'un module complémentaire Internet Explorer 8 fonctionnel

J'utilise Visual Studio 2010 , C # 4 , .Net Framework 4 , donc certaines de ces étapes peuvent être légèrement différentes pour vous.

Création d'une bibliothèque de classes. J'ai appelé le mien InternetExplorerExtension .

Ajoutez ces références au projet:

  • Interop.SHDocVw
  • Microsoft.mshtml

Remarque: Ces références peuvent se trouver à différents endroits sur chaque ordinateur.

voici ce que contient ma section références dans 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" />

Créez les fichiers de la même manière que les fichiers IE11 mis à jour.

IEAddon.cs

Vous pouvez décommenter les lignes suivantes de la version 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

Identique à la version IE11.

et enfin un formulaire, que nous utiliserons pour configurer les options. Dans ce formulaire, placez un TextBoxet un Ok Button. Réglez DialogResult du bouton sur Ok . Le code est le même pour l'addon IE11.

Dans les propriétés du projet, procédez comme suit:

  • Signez l'assemblage avec une touche forte;
  • Dans l'onglet Déboguer, définissez Démarrer le programme externe surC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Dans l'onglet Déboguer, définissez Arguments de ligne de commande surhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Dans l'onglet Générer des événements, définissez la ligne de commande des événements post-génération sur:

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

Attention: comme mon ordinateur est x64, il y a un x64 spécifique à l'intérieur du chemin de l'exécutable gacutil sur ma machine qui peut être différent sur le vôtre.

IE 64 bits a besoin de BHO compilé en 64 bits et enregistré en 64 bits. Utilisez RegAsm.exe 64 bits (réside généralement dans C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Comment fonctionne ce module complémentaire

Il parcourt tout l'arborescence DOM, remplaçant le texte, configuré à l'aide du bouton, par lui-même avec un fond jaune. Si vous cliquez sur les textes jaunis, cela appelle une fonction javascript qui a été insérée dynamiquement sur la page. Le mot par défaut est «navigateur», de sorte qu'il correspond à beaucoup d'entre eux! EDIT: après avoir changé la chaîne à mettre en surbrillance, vous devez cliquer sur la case URL et appuyer sur Entrée ... F5 ne fonctionnera pas, je pense que c'est parce que F5 est considéré comme 'navigation', et il faudrait l'écouter pour naviguer l'événement (peut être). J'essaierai de résoudre ce problème plus tard.

Maintenant, il est temps de partir. Je suis très fatigué. N'hésitez pas à poser des questions ... peut-être que je ne pourrai pas répondre puisque je pars en voyage ... dans 3 jours je serai de retour, mais j'essaierai de venir ici en attendant.


2
Salut, j'ai fait exactement ce qui est décrit dans la réponse. Le bouton apparaît. La fonction d'exécution est exécutée. Cependant, les fonctions SetSite et GetSite ne sont jamais appelées. Je veux pouvoir connaître l'URL de la page sur laquelle je me trouve. Il ne parvient pas à appeler ces méthodes pour initialiser le navigateur .. Aidez
moi

3
J'ai essayé de le faire sur IE9 et: 1. Si votre chemin de projet a des espaces: au lieu d' $(TargetDir)$(TargetFileName)utiliser "$(TargetDir)$(TargetFileName)" 2. Si vous utilisez Visual Studio 2010 Express, vous ne voyez probablement pas (je fais) l' option Démarrer le programme externe dans l'onglet Déboguer - je exécutez simplement IE et accédez à l'URL fournie 3. Cela ne semble pas fonctionner sur IE9 - je peux ouvrir le formulaire (options de surligneur) mais je ne sais pas comment le mettre en surbrillance le texte
pinus.acer

8
Pour la référence Interop.SHDocVw - à la place, vous devez ajouter une référence COM à «Microsoft Internet Controls», puis «using SHDocVw;»
Eric Hartford

8
"IE10 sur x64 Windows 8 ne chargera pas votre module complémentaire au démarrage, à moins que vous ne construisiez avec l'architecture" N'importe quel processeur "et que vous vous inscriviez à l'aide de RegAsm.exe 32 et 64 bits." était une modification par quelqu'un qui a été rejetée.
Matsemann

3
Veuillez consulter le suivi: stackoverflow.com/questions/22953571/…

12

Une autre approche intéressante serait de vérifier:

http://www.crossrider.org

C'est un framework basé sur JS avec jquery qui vous permet de développer des extensions de navigateur pour IE, FF et Chrome en utilisant un seul code JS commun. Fondamentalement, le cadre fait tout le travail désagréable et il vous reste à écrire le code de vos applications.


Ouais, c'est vraiment la voie à suivre, évitant également le cauchemar qui développe un plugin dans Visual Studio, cela signifie que vous n'avez à écrire votre plugin qu'une seule fois pour tous les navigateurs. Cela signifie également ne pas avoir à développer dans une machine virtuelle si vous êtes un utilisateur Mac.
opsb

11

L'état des extensions IE est en fait assez triste. Vous avez l'ancien modèle de IE5 Browser Helper Object (ouais, ces fameux BHO que tout le monde aimait bloquer dans la journée), les barres d'outils et les nouveaux accélérateurs pour IE. Même alors, la compatibilité se brisera parfois. J'ai utilisé pour maintenir une extension pour IE6 qui a rompu avec IE7, donc il y a des choses qui ont changé. Pour la plupart, pour autant que je sache (je n'ai pas touché aux BHO depuis des années), vous devez toujours les coder en utilisant les bibliothèques de modèles actifs (un peu comme une STL pour COM de Microsoft) et ainsi, c'est uniquement pour C ++. Vous pouvez faire COM Interop avec C # et vous en sortir en C # mais cela va probablement être trop difficile pour ce que cela vaut. En tous cas,

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

Et pour les accélérateurs qui sont nouveaux dans IE8, vous pouvez vérifier celui-ci.

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

Je suis d'accord que la documentation est terrible et les API sont assez obsolètes. J'espère toujours que cela aide.

EDIT: Je suppose que je peux jeter une dernière source d'information ici. Je regardais mes notes de dos quand je travaillais sur les BHO. Et c'est l'article qui m'a permis de commencer avec eux. Il est un peu ancien, mais a une bonne explication des interfaces ATL que vous utiliserez lorsque vous travaillerez avec des BHO IE (IObjectWithSite par exemple). Je pense que c'est assez bien expliqué et cela m'a beaucoup aidé à l'époque. http://msdn.microsoft.com/en-us/library/bb250436.aspx J'ai également vérifié l'exemple publié par GregC. Il fonctionne avec au moins IE8 et il est compatible avec VS 2010, donc si vous voulez faire du C #, vous pouvez vous y lancer et jeter un œil au livre de Jon Skeet. (C # in Depth 2nd edition) Le chapitre 13 contient de nombreuses informations sur les nouvelles fonctionnalités de C # 4 que vous pouvez utiliser pour rendre l'interaction avec COM plus agréable. (Je vous recommanderais quand même de faire votre addin en C ++)


6

Le développement de C # BHOs ​​est une douleur dans le cul. Cela implique beaucoup de code COM icky et d'appels p / invoke.

J'ai un C # BHO presque fini ici , que vous êtes libre d'utiliser la source pour tout ce que vous voulez. Je dis «surtout» , car je n'ai jamais compris comment enregistrer les données d'application sous le mode protégé IE .


4
C # 4.0 pourrait être meilleur à cet égard, car COM Interop est beaucoup amélioré.
Robert Harvey

@Robert: Vraiment? Je n'avais aucune idée ... quelles sont les différences?
user541686

@Mehrdad: Vous pouvez avoir un aperçu des différences ici: devx.com/dotnet/Article/42590/1954 . Pour une discussion plus approfondie, voir le discours d'Anders Hejlsberg, "The Future of C #", ici: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey

1
@Robert @Mehrdad: Pas vraiment. Ce n'est pas l'interopérabilité COM qui est icky (à cet égard) , il développe et enregistre un module COM, avec lequel les nouvelles fonctionnalités C # 4.0 ne permettent pas.
BlueRaja - Danny Pflughoeft

4

Je travaille avec le contrôle du navigateur Web d'IE depuis des années maintenant, et au cours d'eux, un nom revient sans cesse avec des publications utiles: Igor Tandetnik

Si je développais une extension, je ciblerais un BHO et commencerais à googler pour:

BHO Igor Tandetnik

OU

Objet d'aide du navigateur Igor Tandetnik

Ses messages sont souvent très détaillés et il sait de quoi il parle.

Vous allez vous retrouver à vos oreilles dans la programmation COM et ATL. Pour un exemple de procédure pas à pas, consultez: http://msdn.microsoft.com/en-us/library/ms976373.aspx


Le plus gros inconvénient de l'utilisation de C # (qui est la direction que prennent la plupart des autres affiches) est qu'il va passer par toutes sortes de couches supplémentaires, avec une solution de contournement et des correctifs pour le code natif de C ++.
Lynn Crumbling



3

C'est évidemment résolu, mais pour les autres utilisateurs, je recommanderais le framework SpicIE . J'ai créé ma propre extension sur cette base. Il ne prend officiellement en charge Internet Explorer 7/8, mais je l'ai testé sur Internet Explorer 6-10 (de Windows XP à Windows 8 Consumer Preview) et cela fonctionne très bien . Malheureusement, il y avait quelques bugs dans la dernière version, j'ai donc dû les corriger et j'ai fait ma propre version: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251


0

Je vous propose chaleureusement ce post de Pavel Zolnikov publié en 2002!

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

Il est basé sur l'utilisation d'objets Band et est compilé à l'aide de .Net 2.0. Le code source est fourni et s'ouvre et se compile bien avec Visual Studio 2013. Comme vous le lirez dans les commentaires, il fonctionne parfaitement bien pour IE 11 et sur Windows 7 et Windows 10. Il fonctionnait parfaitement bien pour moi sur Windows 7 + SP1 et IE 11 Profitez-en!


Nous aimons que les réponses soient autonomes sur StackOverflow. Tout ce post me dit vraiment "utiliser des objets Band et .Net 2.0". Pourriez-vous inclure un exemple de code ici pour montrer comment cela pourrait être fait?
Teepeemm

0

La question est de 2013, maintenant c'est 2020, mais cela peut être utile pour les futurs visiteurs.

J'ai essayé de mettre en œuvre la réponse de @Miguel Angelo, cela n'a pas fonctionné au début.

Il reste encore quelques paramètres à définir.

sur Internet Explorer (j'utilise IE-11) allez sur Tools-->Internet Options-->Advanced: entrez la description de l'image ici

entrez la description de l'image ici

Voir aussi cette question SO et cet exemple de github


-2

entrez la description de l'image ici

Dans l'onglet Build Events, définissez la ligne de commande des événements post-build sur: (x64) est répertorié ci-dessous

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

Je veux que l'onglet Build Events, définisse la ligne de commande des événements post-build sur (système d'exploitation 32 bits)

"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)"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.