Làm thế nào để bắt đầu với việc phát triển các phần mở rộng Internet Explorer?


207

Có ai ở đây có kinh nghiệm với / trong việc phát triển các tiện ích mở rộng IE có thể chia sẻ kiến ​​thức của họ không? Điều này sẽ bao gồm các mẫu mã, hoặc liên kết đến những cái tốt, hoặc tài liệu về quy trình, hoặc bất cứ điều gì.

Tôi thực sự muốn làm điều này, nhưng tôi đang va vào một bức tường khổng lồ với tài liệu tệ hại, mã tệ hại / mã ví dụ / thiếu nó. Bất kỳ trợ giúp / tài nguyên bạn có thể cung cấp sẽ được đánh giá rất cao.

Cụ thể, tôi muốn bắt đầu với cách truy cập / thao tác DOM từ trong tiện ích mở rộng IE.

EDIT, thậm chí nhiều chi tiết hơn:

Lý tưởng nhất, tôi muốn đặt một nút thanh công cụ, khi nhấp vào, bật một menu lên có chứa các liên kết đến các trang web bên ngoài. Tôi cũng muốn truy cập DOM và trồng JavaScript trên trang tùy thuộc vào một số điều kiện.

Cách tốt nhất để duy trì thông tin trong một phần mở rộng IE là gì? Trong Firefox / Chrome / Hầu hết các trình duyệt hiện đại, bạn sử dụngwindow.localStorage , nhưng rõ ràng với IE8 / IE7, đó không phải là một tùy chọn. Có lẽ một SQLite DB hoặc như vậy? Bạn có thể giả sử rằng .NET 4.0 sẽ được cài đặt trên máy tính của người dùng không?

Tôi không muốn sử dụng Spice IE vì tôi cũng muốn xây dựng một phiên bản tương thích với IE9. Tôi cũng đã thêm thẻ C ++ vào câu hỏi này, vì nếu xây dựng một thẻ trong C ++ tốt hơn, tôi có thể làm điều đó.


1
IMHO IE 9 là đơn đặt hàng có cường độ tốt hơn các phiên bản trước. (Tất nhiên, tôi sẽ không rời Chrome vì IE ... dù sao đi nữa.)
user541686

1
@Alex: bạn sắp xếp những thứ gì để triển khai trong IE, để chúng ta có thể bắt đầu đào theo đúng hướng chung?
GregC

@Alex: Để chia nhỏ vấn đề này thành các phần có thể quản lý, tôi cần biết những điều sau: chúng ta có thể giả sử rằng người dùng cuối sẽ chạy IE9 và sẽ sẵn sàng cài đặt thời gian chạy dotNET 4.0 không?
GregC

Tôi đồng ý với GregC. Một số thông tin sẽ giúp ở đây. Bạn đang suy nghĩ về một cái gì đó như thanh công cụ, hoặc có thể một cái gì đó sẽ xử lý trước những gì người dùng đang duyệt hoặc một cái gì đó sẽ kết nối với dịch vụ của bên thứ ba.
cloudraven

4
@Alex, hãy xem Crossrider . Nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều.
shdev

Câu trả lời:


229

[CẬP NHẬT] Tôi đang cập nhật câu trả lời này để hoạt động với Internet Explorer 11 , trong Windows 10 x64 với Cộng đồng Visual Studio 2017 . Phiên bản trước của câu trả lời này (dành cho Internet Explorer 8, trong Windows 7 x64 và Visual Studio 2010) nằm ở cuối câu trả lời này.

Tạo một bổ trợ Internet Explorer 11 hoạt động

Tôi đang sử dụng Cộng đồng Visual Studio 2017 , C # , .Net Framework 4.6.1 , vì vậy một số bước này có thể hơi khác với bạn.

Bạn cần mở Visual Studio với tư cách Quản trị viên để xây dựng giải pháp, để tập lệnh hậu xây dựng có thể đăng ký BHO (cần quyền truy cập đăng ký).

Bắt đầu bằng cách tạo một thư viện lớp. Tôi đã gọi cho tôi InternetExplorerExtension .

Thêm các tham chiếu này vào dự án:

  • Interop.SHDocVw: tab COM / tìm kiếm "Microsoft Internet Controls"
  • Microsoft.mshtml: tab lắp ráp / tìm kiếm "Microsoft.mshtml"

Lưu ý: Bằng cách nào đó MSHTML không được đăng ký trong hệ thống của tôi, mặc dù tôi có thể tìm thấy trong cửa sổ Thêm tham chiếu. Điều này gây ra lỗi trong khi xây dựng:

Không thể tìm thấy trình bao bọc cho thư viện kiểu "MSHTML"

Bản sửa lỗi có thể được tìm thấy tại http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assinstall-for.html Hoặc, bạn có thể chạy tập lệnh bó này:

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

Tạo các tệp sau:

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

và cuối cùng là một hình thức, mà chúng ta sẽ sử dụng để cấu hình các tùy chọn. Trong hình thức này, đặt một TextBoxvà một Ok Button. Đặt DialogResult của nút thành Ok . Đặt mã này vào mã mẫu:

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

Trong các thuộc tính của dự án, làm như sau:

  • Ký tên lắp ráp với một phím mạnh;
  • Trong tab Gỡ lỗi, đặt Bắt đầu Chương trình Bên ngoài thànhC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Trong tab Gỡ lỗi, đặt Đối số dòng lệnh thànhhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Trong tab Xây dựng sự kiện, đặt dòng lệnh Sự kiện xây dựng sau thành:

    "% ProgramFiles (x86)% \ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.6.1 Công cụ \ gacutil.exe" / f / i "$ (TargetDir) $ (TargetFileName)"
    
    "% Windir% \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" / hủy đăng ký "$ (TargetDir) $ (TargetFileName)"
    
    "% Windir% \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" "$ (TargetDir) $ (TargetFileName)"

Chú ý: mặc dù máy tính của tôi là x64, tôi đã sử dụng đường dẫn của non-x64 gacutil.exevà nó hoạt động ... một cái cụ thể cho x64 là:

C: \ Tệp chương trình (x86) \ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.6.1 Công cụ \ x64 \ gacutil.exe

Nhu cầu IE 64 bit được biên dịch 64 bit và BHO đăng ký 64 bit. Mặc dù tôi chỉ có thể gỡ lỗi bằng IE11 32 bit, nhưng tiện ích mở rộng đã đăng ký 32 bit cũng hoạt động bằng cách chạy IE11 64 bit.

Câu trả lời này dường như có một số thông tin bổ sung về điều này: https://stackoverflow.com/a/23004613/195417

Nếu bạn cần, bạn có thể sử dụng hồi quy 64 bit:

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

Cách bổ trợ này hoạt động

Tôi đã không thay đổi hành vi của tiện ích bổ sung ... hãy xem phần IE8 dưới đây để mô tả.


## Câu trả lời trước cho IE8

Man ... đây là một công việc rất nhiều! Tôi đã rất tò mò về cách làm điều này, mà tôi đã tự làm nó.

Trước hết ... tín dụng không phải là tất cả của tôi. Đây là một bản tổng hợp những gì tôi tìm thấy, trên các trang web này:

Và tất nhiên, tôi muốn câu trả lời của tôi có các tính năng bạn đã hỏi:

  • DOM traversal để tìm một cái gì đó;
  • một nút hiển thị một cửa sổ (trong trường hợp của tôi để thiết lập)
  • duy trì cấu hình (tôi sẽ sử dụng registry cho điều đó)
  • và cuối cùng thực thi javascript.

Tôi sẽ mô tả từng bước một, cách tôi quản lý để làm việc với Internet Explorer 8 , trong Windows 7 x64 ... lưu ý rằng tôi không thể kiểm tra các cấu hình khác. Mong bạn hiểu =)

Tạo một bổ trợ Internet Explorer 8 hoạt động

Tôi đang sử dụng Visual Studio 2010 , C # 4 , .Net Framework 4 , vì vậy một số bước này có thể hơi khác với bạn.

Tạo một thư viện lớp. Tôi gọi tôi là InternetExplorerExtension .

Thêm các tham chiếu này vào dự án:

  • Interop.SHDocVw
  • Microsoft.mshtml

Lưu ý: Các tài liệu tham khảo này có thể ở những nơi khác nhau trong mỗi máy tính.

đây là phần tham chiếu của tôi trong csproj chứa:

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

Tạo các tệp giống như các tệp IE11 được cập nhật.

IEAddon.cs

Bạn có thể bỏ ghi chú các dòng sau từ phiên bản 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

Tương tự như phiên bản IE11.

và cuối cùng là một hình thức, mà chúng ta sẽ sử dụng để cấu hình các tùy chọn. Trong hình thức này, đặt một TextBoxvà một Ok Button. Đặt DialogResult của nút thành Ok . Mã này giống với addon IE11.

Trong các thuộc tính của dự án, làm như sau:

  • Ký tên lắp ráp với một phím mạnh;
  • Trong tab Gỡ lỗi, đặt Bắt đầu Chương trình bên ngoài thànhC:\Program Files (x86)\Internet Explorer\iexplore.exe
  • Trong tab Gỡ lỗi, đặt Đối số dòng lệnh thànhhttp://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • Trong tab Xây dựng sự kiện, đặt dòng lệnh Sự kiện xây dựng sau thành:

    "C: \ Tệp chương trình (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ NETFX 4.0 Công cụ \ x64 \ gacutil.exe" / f / i "$ (TargetDir) $ (TargetFileName)"
    
    "C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" / hủy đăng ký "$ (TargetDir) $ (TargetFileName)"
    
    "C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" "$ (TargetDir) $ (TargetFileName)"

Chú ý: vì máy tính của tôi là x64, có một x64 cụ thể bên trong đường dẫn thực thi gacutil trên máy của tôi có thể khác với máy của bạn.

IE 64 bitNhu cầu 64 bit được biên dịch 64 bit và BHO đăng ký 64 bit. Sử dụng RegAsm.exe 64 bit (thường sống trong C: \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe)

Cách bổ trợ này hoạt động

Nó đi qua tất cả cây DOM, thay thế văn bản, được định cấu hình bằng nút, bằng nền màu vàng. Nếu bạn nhấp vào các văn bản màu vàng, nó sẽ gọi một hàm javascript được chèn trên trang một cách linh hoạt. Từ mặc định là 'trình duyệt', vì vậy nó phù hợp với rất nhiều từ đó! EDIT: sau khi thay đổi chuỗi được tô sáng, bạn phải nhấp vào hộp URL và nhấn Enter ... F5 sẽ không hoạt động, tôi nghĩ rằng đó là vì F5 được coi là 'điều hướng' và nó sẽ yêu cầu lắng nghe để điều hướng sự kiện (có lẽ). Tôi sẽ cố gắng khắc phục điều đó sau.

Bây giờ, đã đến lúc phải đi. Tôi rất mệt. Vui lòng đặt câu hỏi ... có thể tôi sẽ không thể trả lời vì tôi đang đi du lịch ... trong 3 ngày tôi sẽ quay lại, nhưng tôi sẽ cố gắng đến đây trong thời gian này.


2
Xin chào, tôi đã làm chính xác những gì được mô tả trong câu trả lời. Nút đang xuất hiện. Các funtion exec được thực hiện. Tuy nhiên, các hàm SetSite và GetSite không bao giờ được gọi. Tôi muốn có thể biết URL của trang tôi đang truy cập. Không thể gọi các phương thức này để khởi tạo trình duyệt .. Xin hãy giúp đỡ
mustafabar

3
Tôi đã thử thực hiện điều này trên IE9 và: 1. Nếu đường dẫn dự án của bạn có khoảng trắng: thay vì $(TargetDir)$(TargetFileName)sử dụng "$(TargetDir)$(TargetFileName)" 2. Nếu bạn sử dụng Visual Studio 2010 Express, có lẽ bạn không thấy tùy chọn Bắt đầu chương trình bên ngoài trong tab Gỡ lỗi - Tôi chỉ cần chạy IE và điều hướng đến URL được cung cấp 3. Có vẻ như nó không hoạt động trên IE9 - Tôi có thể mở biểu mẫu (tùy chọn Công cụ tô sáng) nhưng tôi không biết cách làm nổi bật văn bản
pinus.acer

8
Đối với tham chiếu Interop.SHDocVw - thay vào đó, bạn nên thêm tham chiếu COM vào "Điều khiển Internet của Microsoft" và sau đó "sử dụng SHDocVw;"
Eric Hartford

8
"IE10 trên x64 Windows 8 sẽ không tải bổ trợ của bạn khi bắt đầu trừ khi bạn sẽ xây dựng với kiến ​​trúc" Bất kỳ CPU "và đăng ký bằng cả RegAsm.exe 32 và 64 bit." là một chỉnh sửa bởi một người đã bị từ chối.
Matsemann


12

Một cách tiếp cận thú vị khác là kiểm tra:

http://www.crossrider.org

Đó là một khung dựa trên JS với jquery cho phép bạn phát triển các tiện ích mở rộng trình duyệt cho IE, FF và Chrome bằng một mã JS phổ biến duy nhất. Về cơ bản, khung công tác thực hiện tất cả các công việc khó chịu và bạn còn lại với việc viết mã ứng dụng của mình.


Vâng, đây thực sự là con đường để đi, cũng như tránh cơn ác mộng đang phát triển một plugin trong visual studio, điều đó có nghĩa là bạn chỉ phải viết plugin của mình một lần cho tất cả các trình duyệt. Điều đó cũng có nghĩa là không phải phát triển trong một máy ảo nếu bạn là người dùng mac.
opsb

11

Trạng thái cho các phần mở rộng IE thực sự khá buồn. Bạn có mô hình cũ của Đối tượng trợ giúp trình duyệt IE5 (vâng, những BHO khét tiếng mà mọi người thích chặn lại trong ngày), thanh công cụ và trình tăng tốc mới cho IE. Thậm chí sau đó, khả năng tương thích đôi khi sẽ bị phá vỡ. Tôi đã từng duy trì một phần mở rộng cho IE6 đã bị hỏng với IE7, vì vậy có một số điều đã thay đổi. Đối với hầu hết các phần, theo như tôi biết (tôi đã không chạm vào BHOs ​​trong nhiều năm), bạn vẫn cần mã hóa chúng bằng Thư viện mẫu hoạt động (giống như STL cho COM của Microsoft) và cũng như vậy chỉ dành cho C ++. Bạn có thể thực hiện COM Interop với C # và thoát khỏi việc thực hiện nó trong C # nhưng có lẽ nó sẽ quá khó cho những gì đáng giá. Dù sao,

http://msdn.microsoft.com/en-us/l Library / aa753587 (v ​​= vs85) .aspx

Và đối với các máy gia tốc mới trong IE8, bạn có thể kiểm tra cái này.

http://msdn.microsoft.com/en-us/l Library / cc289775 (v = vs85) .aspx

Tôi đồng ý tài liệu này rất tệ và các API khá lỗi thời. Tôi vẫn hy vọng điều này sẽ giúp.

EDIT: Tôi đoán tôi có thể ném một nguồn thông tin cuối cùng ở đây. Tôi đã xem qua các ghi chú của tôi khi tôi làm việc trên BHOs. Và đây là bài viết khiến tôi bắt đầu với họ. Nó khá cũ, nhưng có một lời giải thích tốt về các giao diện ATL mà bạn sẽ sử dụng khi làm việc với IE BHOs ​​(ví dụ IObjectWithSite). Tôi nghĩ rằng nó được giải thích khá tốt và đã giúp tôi rất nhiều sau đó. http://msdn.microsoft.com/en-us/l Library / bb250436.aspx Tôi cũng đã kiểm tra ví dụ mà GregC đã đăng. Nó hoạt động với ít nhất IE8 và tương thích với VS 2010, vì vậy nếu bạn muốn làm C #, bạn có thể bắt đầu ở đó và xem cuốn sách của Jon Skeet. (C # trong phiên bản Depth 2nd) Chương 13 có rất nhiều thông tin về các tính năng mới trong C # 4 mà bạn có thể sử dụng để làm cho tương tác với COM đẹp hơn. (Tôi vẫn sẽ khuyên bạn nên thực hiện addin của mình trong C ++)


6

Phát triển C # BHOs ​​là một công việc khó khăn. Nó liên quan đến rất nhiều mã COM icky và các cuộc gọi p / gọi.

Tôi có một C # BHO đã hoàn thành ở đây , bạn có thể tự do sử dụng nguồn cho bất cứ điều gì bạn muốn. Tôi nói "chủ yếu" , bởi vì tôi chưa bao giờ tìm ra cách lưu appdata trong Chế độ bảo vệ IE .


4
C # 4.0 có thể tốt hơn về vấn đề này, vì COM Interop được cải thiện hơn nhiều.
Robert Harvey

@Robert: Thật sao? Tôi không biết ... sự khác biệt là gì?
dùng541686

@Mehrdad: Bạn có thể cảm nhận sự khác biệt ở đây: devx.com/dotnet/Article/42590/1954 . Để có một cuộc thảo luận sâu hơn, hãy xem bài nói chuyện của Anders Hejlsberg, "Tương lai của C #," tại đây: channel9.msdn.com/Blogs/pdc2008/TL16
Robert Harvey

1
@Robert @Mehrdad: Không thực sự. Không phải là COM interop là icky (về mặt này) , nó đang phát triển và đăng ký một mô-đun COM, mà các tính năng C # 4.0 mới không giúp được.
BlueRaja - Daniel Pflughoeft

4

Tôi đã làm việc với kiểm soát webbrowser của IE trong nhiều năm nay và qua quá trình của họ, một cái tên xuất hiện lặp đi lặp lại với các bài đăng hữu ích: Igor Tandetnik

Nếu tôi đang phát triển một tiện ích mở rộng, tôi sẽ nhắm mục tiêu BHO và bắt đầu tìm kiếm:

BHO Igor Tandetnik

HOẶC LÀ

Đối tượng trợ giúp trình duyệt Igor Tandetnik

Các bài đăng của anh ấy thường rất chi tiết, và anh ấy biết những gì anh ấy đang nói về.

Bạn sẽ thấy mình đến tai trong lập trình COM và ATL. Để biết hướng dẫn mẫu, hãy xem: http://msdn.microsoft.com/en-us/l Library / ms976373.aspx


Nhược điểm lớn nhất của việc sử dụng C # (đó là hướng mà hầu hết các áp phích khác đang diễn ra) là nó sẽ trải qua tất cả các loại lớp bổ sung, với cách khắc phục và bản vá cho mã có nguồn gốc từ C ++.
Lynn Crumbled


3

Nếu bạn không cố gắng phát minh lại bánh xe, bạn có thể thử Add In Express cho IE . Tôi đã sử dụng sản phẩm cho các công cụ VSTO , và nó khá tốt. Ngoài ra họ có một diễn đàn hữu ích và hỗ trợ nhanh chóng.


3

Rõ ràng là đã được giải quyết, nhưng đối với những người dùng khác, tôi muốn giới thiệu khung SpicIE . Tôi đã thực hiện phần mở rộng của riêng mình dựa trên nó. Nó chỉ hỗ trợ Internet Explorer 7/8 chính thức, nhưng tôi đã thử nghiệm điều đó trên Internet Explorer 6-10 (từ Windows XP đến Windows 8 Consumer Preview) và nó hoạt động tốt . Thật không may, có một số lỗi trong bản phát hành mới nhất, vì vậy tôi đã phải sửa chúng và tự phát hành: http://archive.msdn.microsoft.com/SpicIE/Thread/View.aspx?ThreadId=5251


0

Tôi nồng nhiệt đề nghị bạn bài này của Pavel Zolnikov xuất bản năm 2002!

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

Nó dựa trên việc sử dụng các đối tượng Band và được biên dịch bằng .Net 2.0. Mã nguồn được cung cấp và mở và biên dịch tốt với Visual Studio 2013. Như bạn sẽ đọc trên các bình luận bài đăng, nó hoạt động hoàn toàn tốt cho IE 11 và trên Windows 7 và Windows 10. Nó hoạt động hoàn hảo với tôi trên Windows 7 + SP1 và IE 11 Thưởng thức!


Chúng tôi muốn các câu trả lời được chứa trong StackOverflow. Tất cả bài đăng này thực sự cho tôi biết là "sử dụng các đối tượng Band và .Net 2.0". Bạn có thể bao gồm một số mã mẫu ở đây để cho thấy làm thế nào nó có thể được thực hiện?
Teepeemm

0

Câu hỏi là từ năm 2013, bây giờ là năm 2020, nhưng nó có thể hữu ích cho khách truy cập trong tương lai.

Tôi đã cố gắng thực hiện câu trả lời của @Miguel Angelo, nó đã không hoạt động ngay từ đầu.

Vẫn còn một số cài đặt mà bạn được xác định.

trên internet explorer (Tôi đang sử dụng IE-11), hãy truy cập Tools-->Internet Options-->Advanced: nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Cũng xem câu hỏi SO nàyví dụ này từ github


-2

nhập mô tả hình ảnh ở đây

Trong tab Xây dựng sự kiện, đặt dòng lệnh Sự kiện xây dựng sau thành: (x64) được liệt kê bên dưới

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

Tôi muốn tab Build Events, đặt dòng lệnh Sự kiện xây dựng sau thành (hệ điều hành 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)"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.