Como começar a desenvolver extensões do Internet Explorer?

207

Alguém aqui tem experiência com / no desenvolvimento de extensões do IE que podem compartilhar seus conhecimentos? Isso incluiria exemplos de código, links para bons, documentação do processo ou qualquer outra coisa.

Eu realmente quero fazer isso, mas estou atingindo uma parede gigante com documentação ruim, código ruim / código de exemplo / falta dela. Qualquer ajuda / recursos que você possa oferecer seria muito apreciada.

Especificamente, eu gostaria de começar com como obter / manipular o DOM de dentro de uma extensão do IE.

EDIT, ainda mais detalhes:

Idealmente, gostaria de plantar um botão da barra de ferramentas que, quando clicado, exibia um menu que contém links para sites externos. Também gostaria de acessar o DOM e plantar JavaScript na página, dependendo de algumas condições.

Qual é a melhor maneira de manter as informações em uma extensão do IE? No Firefox / Chrome / A maioria dos navegadores modernos, você usa window.localStorage, mas obviamente com o IE8 / IE7, essa não é uma opção. Talvez um banco de dados SQLite ou algo assim? Não há problema em supor que o .NET 4.0 será instalado no computador de um usuário?

Não quero usar o Spice IE, pois quero criar um que seja compatível com o IE9. Também adicionei a tag C ++ a essa pergunta, porque se for melhor criar uma em C ++, eu posso fazer isso.

Alex
fonte
1
O IMHO IE 9 é uma ordem de magnitude melhor que as versões anteriores. (Não que eu vou deixar Chrome para o IE é claro ... mas não de qualquer maneira.)
user541686
1
@ Alex: que tipo de coisas você pensa em implementar no IE, para que possamos começar a cavar na direção geral certa?
Gregc
@ Alex: Para quebrar esse problema em partes gerenciáveis, eu precisaria saber o seguinte: podemos supor que o usuário final esteja executando o IE9 e esteja disposto a instalar o tempo de execução do dotNET 4.0?
Gregc
Eu concordo com GregC. Mais algumas informações ajudarão aqui. Você está pensando em algo como uma barra de ferramentas, ou talvez algo que pré-processe o que o usuário está navegando ou algo que irá se conectar a um serviço de terceiros.
cloudraven
4
@ Alex, dê uma olhada no Crossrider . Isso tornará sua vida muito mais fácil.
shdev 4/07

Respostas:

229

[UPDATE] Estou atualizando esta resposta para funcionar com o Internet Explorer 11 , na comunidade Windows 10 x64 com Visual Studio 2017 . A versão anterior desta resposta (para Internet Explorer 8, no Windows 7 x64 e no Visual Studio 2010) está na parte inferior desta resposta.

Criando um complemento funcional do Internet Explorer 11

Estou usando a Comunidade do Visual Studio 2017 , C # , .Net Framework 4.6.1 , portanto, algumas dessas etapas podem ser um pouco diferentes para você.

Você precisa abrir o Visual Studio como administrador para criar a solução, para que o script pós-compilação possa registrar o BHO (precisa de acesso ao registro).

Comece criando uma biblioteca de classes. Liguei para o meu InternetExplorerExtension .

Adicione estas referências ao projeto:

  • Interop.SHDocVw: guia COM / pesquisa por "Microsoft Internet Controls"
  • Microsoft.mshtml: guia Assemblies / procure por "Microsoft.mshtml"

Nota: De alguma forma, o MSHTML não estava registrado no meu sistema, mesmo que eu pudesse encontrá-lo na janela Adicionar referência. Isso causou um erro ao criar:

Não foi possível encontrar o conjunto do wrapper para a biblioteca de tipos "MSHTML"

A correção pode ser encontrada em http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html Ou você pode executar este script em lote:

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

Crie os seguintes arquivos:

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 finalmente um formulário que usaremos para configurar as opções. Nesse formulário, coloque um TextBoxe um Ok Button. Defina o DialogResult do botão como OK . Coloque este código no código do formulário:

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

Nas propriedades do projeto, faça o seguinte:

  • Assine a montagem com uma chave forte;
  • Na guia Debug, defina Start External Program comoC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Na guia Debug, defina Argumentos da linha de comando comohttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Na guia Build Events, defina a linha de comando Post-build events para:

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

Atenção: mesmo que meu computador seja x64, usei o caminho do não-x64 gacutil.exee funcionou ... o específico para x64 é:

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

IE de 64 bits Precisa de BHO compilado e registrado em 64 bits. Embora eu só pudesse depurar usando o IE11 de 32 bits, a extensão registrada de 32 bits também funcionava executando o IE11 de 64 bits.

Esta resposta parece ter algumas informações adicionais sobre isso: https://stackoverflow.com/a/23004613/195417

Se necessário, você pode usar o regime de 64 bits:

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

Como este complemento funciona

Não mudei o comportamento do complemento ... dê uma olhada na seção IE8 abaixo para obter uma descrição.


## Resposta anterior para o IE8

Cara ... isso tem sido muito trabalho! Eu estava tão curioso sobre como fazer isso, que eu mesmo fiz.

Primeiro de tudo ... crédito não é todo meu. Esta é uma compilação do que encontrei nesses sites:

E, é claro, eu queria que minha resposta tivesse os recursos que você perguntou:

  • DOM atravessar para encontrar algo;
  • um botão que mostra uma janela (no meu caso para configurar)
  • persistir na configuração (usarei o registro para isso)
  • e, finalmente, execute o javascript.

Descreverei passo a passo como consegui trabalhar com o Internet Explorer 8 , no Windows 7 x64 ... observe que não pude testar em outras configurações. Espero que você entenda =)

Criando um complemento funcional do Internet Explorer 8

Estou usando o Visual Studio 2010 , C # 4 , .Net Framework 4 , portanto, algumas dessas etapas podem ser um pouco diferentes para você.

Criou uma biblioteca de classes. Liguei para o meu InternetExplorerExtension .

Adicione estas referências ao projeto:

  • Interop.SHDocVw
  • Microsoft.mshtml

Nota: Essas referências podem estar em locais diferentes em cada computador.

é isso que minha seção de referências no csproj contém:

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

Crie os arquivos da mesma maneira que os arquivos IE11 atualizados.

IEAddon.cs

Você pode descomentar as seguintes linhas da versão 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

O mesmo que a versão IE11.

e finalmente um formulário que usaremos para configurar as opções. Nesse formulário, coloque um TextBoxe um Ok Button. Defina o DialogResult do botão como OK . O código é o mesmo para o complemento IE11.

Nas propriedades do projeto, faça o seguinte:

  • Assine a montagem com uma chave forte;
  • Na guia Debug, defina Start External Program comoC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Na guia Debug, defina Argumentos da linha de comando comohttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Na guia Eventos de Construção, defina a linha de comando Eventos Pós-Construção para:

    "C: \ Arquivos de programas (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" / cancele o registro "$ (TargetDir) $ (TargetFileName)"
    
    "C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" "$ (TargetDir) $ (TargetFileName)"

Atenção: como meu computador é x64, há um x64 específico no caminho do executável gacutil na minha máquina que pode ser diferente do seu.

IE de 64 bits Precisa de BHO compilado e registrado em 64 bits. Use o RegAsm.exe de 64 bits (geralmente reside em C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Como este complemento funciona

Ele percorre toda a árvore DOM, substituindo o texto, configurado usando o botão, por si só com um fundo amarelo. Se você clicar nos textos amarelados, ele chamará uma função javascript que foi inserida na página dinamicamente. A palavra padrão é 'browser', para que corresponda a muitos deles! EDIT: depois de alterar a string a ser destacada, você deve clicar na caixa URL e pressionar Enter ... F5 não funcionará, acho que é porque F5 é considerado como 'navegação' e seria necessário ouvir para navegar no evento (talvez). Vou tentar consertar isso mais tarde.

Agora é hora de partir. Estou muito cansado. Sinta-se à vontade para fazer perguntas ... talvez seja, não poderei responder, pois vou viajar ... daqui a três dias volto, mas tentarei entrar aqui enquanto isso.

Miguel Angelo
fonte
2
Olá, fiz exatamente o que está descrito na resposta. O botão está aparecendo. A função exec é executada. No entanto, as funções SetSite e GetSite nunca são chamadas. Quero saber o URL da página em que estou. Está falhando ao chamar esses métodos para inicializar o navegador. Por favor, ajude
mustafabar
3
Tentei fazer isso no IE9 e: 1. Se o caminho do seu projeto tiver espaços: em vez de $(TargetDir)$(TargetFileName)usar "$(TargetDir)$(TargetFileName)" 2. Se você usa o Visual Studio 2010 Express, provavelmente (eu) não vê a opção Iniciar programa externo na guia Debug - I basta executar IE e navegue para o URL fornecido 3. não parece trabalhar no IE9 - Eu posso abrir o formulário (opções Marcador), mas eu não sei como fazê-lo destacar o texto
pinus.acer
8
Para a referência Interop.SHDocVw - em vez disso, você deve adicionar uma referência COM a "Microsoft Internet Controls" e "usando SHDocVw;"
Eric Hartford
8
"O IE10 no x64 do Windows 8 não carregará o complemento ao iniciar, a menos que você construa com a arquitetura" Qualquer CPU "e registre-se usando o RegAsm.exe de 32 e 64 bits." foi uma edição de alguém que foi rejeitada.
Matsemann 04/04
3
Por favor, veja o seguinte: stackoverflow.com/questions/22953571/…
12

Outra abordagem interessante seria verificar:

http://www.crossrider.org

É uma estrutura baseada em JS com jquery que permite desenvolver extensões de navegador para IE, FF e Chrome usando um único código JS comum. Basicamente, a estrutura faz todo o trabalho desagradável e você fica escrevendo o código de seus aplicativos.

Shaish
fonte
Sim, esse é realmente o caminho a percorrer, além de evitar o pesadelo que está desenvolvendo um plug-in no visual studio, significa que você só precisa escrever seu plug-in uma vez para todos os navegadores. Também significa não ter que desenvolver em uma máquina virtual se você é um usuário de mac.
opsb
11

O estado das extensões do IE é realmente muito triste. Você tem o modelo antigo do IE5 Browser Helper Object (sim, aqueles BHOs ​​famosos que todo mundo gostava de bloquear no passado), barras de ferramentas e os novos aceleradores do IE. Mesmo assim, a compatibilidade será interrompida às vezes. Eu costumava manter uma extensão para o IE6 que rompeu com o IE7, então há algumas coisas que mudaram. Na maior parte do tempo, até onde eu sei (não conheço as BHOs ​​há anos), você ainda precisa codificá-las usando as Active Template Libraries (como uma STL para COM da Microsoft) e, portanto, é apenas para C ++. Você pode fazer a interoperabilidade COM com C # e fazê-lo em c #, mas provavelmente será muito difícil para o que vale a pena. De qualquer forma,

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

E para os aceleradores que são novos no IE8, você pode verificar este.

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

Concordo que a documentação é terrível e as APIs estão desatualizadas. Ainda espero que isso ajude.

Edição: Eu acho que posso jogar uma última fonte de informação aqui. Eu estava olhando minhas anotações quando estava trabalhando em BHOs. E este é o artigo que me iniciou com eles. É meio antigo, mas tem uma boa explicação das interfaces ATL que você usará ao trabalhar com o IE BHOs ​​(IObjectWithSite, por exemplo). Eu acho que está bem explicado e me ajudou muito naquela época. http://msdn.microsoft.com/en-us/library/bb250436.aspx Também verifiquei o exemplo que o GregC postou. Ele funciona com pelo menos o IE8 e é compatível com o VS 2010, portanto, se você quiser fazer C #, pode começar por lá e dar uma olhada no Livro de Jon Skeet. (C # na profundidade 2ª edição) O capítulo 13 contém muitas informações sobre os novos recursos do C # 4 que você pode usar para tornar a interação com o COM mais agradável. (Eu ainda recomendo que você faça seu suplemento em C ++)

cloudraven
fonte
6

Desenvolver C # BHOs ​​é um pé no saco. Envolve muitos códigos COM nojentos e chamadas p / invocação.

Eu tenho um C # BHO finalizado aqui , no qual você é livre para usar a fonte para o que quiser. Digo "principalmente" , porque nunca descobri como salvar os dados do aplicativo no Modo Protegido do IE .

BlueRaja - Danny Pflughoeft
fonte
4
O C # 4.0 pode ser melhor nesse aspecto, pois a interoperabilidade COM é muito melhorada.
Robert Harvey
@Robert: Sério? Eu não tinha idéia ... quais são as diferenças?
user541686
@Mehrdad: Você pode conhecer as diferenças aqui: devx.com/dotnet/Article/42590/1954 . Para uma discussão mais aprofundada, veja a conversa de Anders Hejlsberg, "The Future of C #," aqui: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey
1
@Robert @Mehrdad: Na verdade não. Não é a interoperabilidade COM que é nojenta (nesse aspecto) , está desenvolvendo e registrando um módulo COM, com o qual os novos recursos do C # 4.0 não ajudam.
precisa saber é o seguinte
4

Trabalho com o controle de navegadores da web do IE há anos e, ao longo deles, um nome aparece várias vezes com publicações úteis: Igor Tandetnik

Se eu estivesse desenvolvendo uma extensão, segmentaria uma BHO e começaria a pesquisar no Google:

BHO Igor Tandetnik

OU

Objeto auxiliar do navegador Igor Tandetnik

Suas postagens geralmente são muito detalhadas e ele sabe do que está falando.

Você vai se sentir bem em programação COM e ATL. Para obter um exemplo passo a passo, confira: http://msdn.microsoft.com/en-us/library/ms976373.aspx

Lynn Crumbling
fonte
A maior desvantagem do uso de C # (que é a direção que a maioria dos outros pôsteres está seguindo) é que ele passará por todos os tipos de camadas extras, com soluções alternativas e patches para código que seria nativo em C ++.
Lynn desintegração
3

Se você não está tentando reinventar a roda, tente o Add In Express for IE . Eu usei o produto para o material VSTO , e é muito bom. Eles também têm um fórum útil e suporte rápido.

Sujay Ghosh
fonte
3

Está obviamente resolvido, mas para os outros usuários, eu recomendaria o framework SpicIE . Eu fiz minha própria extensão com base nela. Ele suporta apenas o Internet Explorer 7/8 oficialmente, mas testei isso no Internet Explorer 6-10 (do Windows XP ao Windows 8 Consumer Preview) e funciona bem . Infelizmente, houve alguns bugs na versão mais recente, então tive que corrigi-los e fiz minha própria versão: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251

Pěna
fonte
0

Eu sugiro calorosamente este post de Pavel Zolnikov publicado em 2002!

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

Ele é baseado no uso de objetos Band e é compilado usando o .Net 2.0. O código-fonte é fornecido, abre e compila bem com o Visual Studio 2013. Como você lerá nos comentários da postagem, ele funciona perfeitamente para o IE 11, Windows 7 e Windows 10. Ele funcionou perfeitamente para mim no Windows 7 + SP1 e IE 11 Aproveite!

Marc Charmois
fonte
Gostamos que as respostas sejam independentes no StackOverflow. Todo esse post realmente me diz é "use objetos Band e .Net 2.0". Você poderia incluir algum código de exemplo aqui para mostrar como isso pode ser feito?
Teepeemm 12/09/16
0

A pergunta é de 2013, agora é 2020, mas pode ser útil para futuros visitantes.

Tentei implementar a resposta de @Miguel Angelo, que não funcionou no começo.

Ainda existem algumas configurações que você pode definir.

no Internet Explorer (eu estou usando o IE-11), vá para Tools-->Internet Options-->Advanced: insira a descrição da imagem aqui

insira a descrição da imagem aqui

Veja também esta questão SO e este exemplo no github

Nehorai
fonte
-2

insira a descrição da imagem aqui

Na guia Build Events, defina a linha de comando Post-build events como: (x64) está listado abaixo

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

Quero a guia Build Events, defina a linha de comando de eventos pós-build como (sistema operacional de 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)"
user2564356
fonte