[C#] Internet Explorer 확장 개발을 시작하는 방법은 무엇입니까?

여기 누구나 지식을 공유 할 수있는 IE 확장 기능에 대한 경험이 있습니까? 여기에는 코드 샘플 또는 좋은 샘플에 대한 링크 또는 프로세스 관련 문서 등이 포함됩니다.

나는 이것을 정말로하고 싶지만, 문서가 까다 롭고, 코드 / 예제 코드 / 그 부족으로 거대한 벽에 부딪 치고 있습니다. 귀하가 제공 할 수있는 모든 도움 / 자원은 대단히 감사하겠습니다.

특히 IE 확장 내에서 DOM에 액세스하고 조작하는 방법부터 시작하고 싶습니다.

편집, 더 자세한 내용 :

이상적으로는 클릭하면 외부 사이트에 대한 링크가 포함 된 메뉴가 팝업되는 툴바 버튼을 만들고 싶습니다. 또한 일부 조건에 따라 페이지에 DOM에 액세스하고 JavaScript를 설치하고 싶습니다.

IE 확장에서 정보를 유지하는 가장 좋은 방법은 무엇입니까? Firefox / Chrome / 가장 최신 브라우저에서는을 사용 window.localStorage하지만 분명히 IE8 / IE7에서는 옵션이 아닙니다. 아마도 SQLite DB 또는 그런 것입니까? .NET 4.0이 사용자 컴퓨터에 설치되어 있다고 가정해도 괜찮습니까?

IE9와 호환되는 것을 만들고 싶을 때 Spice IE를 사용하고 싶지 않습니다. 이 질문에도 C ++ 태그를 추가했습니다. C ++로 태그를 작성하는 것이 더 낫다면 그렇게 할 수 있기 때문입니다.



답변

[업데이트] 내가 함께 작업이 대답을 통해 업데이트 인터넷 익스플로러 11 에서, 윈도우 10의 x64비주얼 스튜디오 2017 커뮤니티 . 이 답변의 이전 버전 (Windows 7 x64 및 Visual Studio 2010의 Internet Explorer 8)이이 답변의 맨 아래에 있습니다.

Internet Explorer 11 추가 기능 만들기

내가 사용하고 비주얼 스튜디오 2017 커뮤니티 , C # , 닷넷 프레임 워크 4.6.1 이 단계 중 일부는 당신을 위해 약간 다를 수 있습니다, 그래서.

솔루션을 빌드하려면 Visual Studio를 관리자열어서 빌드 후 스크립트가 BHO를 등록 할 수 있도록해야합니다 (레지스트리 액세스 필요).

클래스 라이브러리를 작성하여 시작하십시오. 내 InternetExplorerExtension 이라고했습니다 .

이 참조를 프로젝트에 추가하십시오.

  • Interop.SHDocVw : COM 탭 / 검색 "Microsoft Internet Controls"
  • Microsoft.mshtml : 어셈블리 탭 / 검색 "Microsoft.mshtml"

참고 : 참조 추가 창에서 찾을 수 있지만 어떻게 든 MSHTML이 시스템에 등록되지 않았습니다. 빌드하는 동안 오류가 발생했습니다.

형식 라이브러리 “MSHTML”에 대한 래퍼 어셈블리를 찾을 수 없습니다.

수정 사항은 http://techninotes.blogspot.com/2016/08/fixing-cannot-find-wrapper-assembly-for.html 에서 찾을 수 있습니다.
또는이 배치 스크립트를 실행할 수 있습니다.

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

다음 파일을 작성하십시오.

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

마지막으로 양식을 작성하여 옵션을 구성하는 데 사용합니다. 이 양식에서 a TextBox와 Ok를 배치하십시오 Button. 버튼 의 DialogResultOk로 설정하십시오 . 이 코드를 양식 코드에 넣으십시오.

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

프로젝트 속성에서 다음을 수행하십시오.

  • 강력한 키로 어셈블리에 서명하십시오.
  • 디버그 탭에서 외부 프로그램 시작C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • 디버그 탭에서 명령 줄 인수http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • 빌드 이벤트 탭에서 빌드 후 이벤트 명령 행 을 다음으로 설정하십시오 .

    "% ProgramFiles (x86) % \ Microsoft SDKs \ Windows \ v10.0A \ bin \ NETFX 4.6.1 Tools \ gacutil.exe"/ f / i "$ (TargetDir) $ (TargetFileName)"
    
    "% windir % \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe"/ unregister "$ (TargetDir) $ (TargetFileName)"
    
    "% windir % \ Microsoft.NET \ Framework \ v4.0.30319 \ RegAsm.exe" "$ (TargetDir) $ (TargetFileName)"

주의 : 내 컴퓨터는 x64이지만 x64가 아닌 경로를 사용 gacutil.exe했으며 x64의 특정 경로는 다음 과 같습니다.

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

64 비트 IE 64 비트 컴파일 및 64 비트 등록 BHO가 필요합니다. 32 비트 IE11 만 사용하여 디버깅 할 수 있었지만 32 비트 등록 된 확장명도 64 비트 IE11을 실행하여 작동했습니다.

이 답변에는 이것에 대한 추가 정보가있는 것으로 보입니다 : https://stackoverflow.com/a/23004613/195417

필요한 경우 64 비트 regasm을 사용할 수 있습니다.

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

이 부가 기능의 작동 방식

추가 기능의 동작을 변경하지 않았습니다 … 설명을 보려면 IE8 섹션을 살펴보십시오.


## IE8에 대한 이전 답변

남자 … 이것은 많은 일이되었습니다! 나는 이것을하는 방법에 대해 너무 궁금해서 스스로 해냈습니다.

우선 … 신용이 전부는 아닙니다. 이것은이 사이트에서 내가 찾은 것을 편집 한 것입니다.

그리고 물론, 나는 당신이 요구 한 기능을 갖기 위해 내 대답을 원했습니다.

  • 무언가를 찾기위한 DOM 탐색;
  • 창을 보여주는 버튼 (필자의 경우 설정)
  • 구성을 유지하십시오 (나는 그것을 위해 레지스트리를 사용할 것입니다)
  • 마지막으로 자바 스크립트를 실행하십시오.

Windows 7 x64 에서 Internet Explorer 8로 작업하는 방법을 단계별로 설명합니다 … 다른 구성에서는 테스트 할 수 없습니다. 당신이 이해 희망 =)

Internet Explorer 8 부가 기능 만들기

내가 사용하고 스튜디오 2010 비주얼 , C # 4 , 닷넷 프레임 워크 4 다음 단계 중 일부는 당신을 위해 약간 다를 수 있습니다, 그래서.

클래스 라이브러리를 만들었습니다. 내 InternetExplorerExtension 이라고했습니다 .

이 참조를 프로젝트에 추가하십시오.

  • Interop.SHDocVw
  • Microsoft.mshtml

참고 : 이러한 참조는 컴퓨터마다 다른 위치에있을 수 있습니다.

이것은 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" />

업데이트 된 IE11 파일과 같은 방식으로 파일을 만듭니다.

IEAddon.cs

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

IE11 버전과 동일합니다.

마지막으로 양식을 작성하여 옵션을 구성하는 데 사용합니다. 이 양식에서 a TextBox와 Ok를 배치하십시오 Button. 버튼 의 DialogResultOk로 설정하십시오 . 코드는 IE11 애드온과 동일합니다.

프로젝트 속성에서 다음을 수행하십시오.

  • 강력한 키로 어셈블리에 서명하십시오.
  • 디버그 탭에서 외부 프로그램 시작C:\Program Files (x86)\Internet Explorer\iexplore.exe
  • 디버그 탭에서 명령 줄 인수http://msdn.microsoft.com/en-us/library/ms976373.aspx#bho_getintouch
  • 빌드 이벤트 탭에서 빌드 후 이벤트 명령 행 을 다음으로 설정하십시오 .

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

주의: 내 컴퓨터가 x64이므로 내 컴퓨터의 gacutil 실행 파일 경로에 특정 x64가있을 수 있습니다.

64 비트 IE 64 비트 컴파일 및 64 비트 등록 BHO가 필요합니다. 64 비트 RegAsm.exe 사용 (일반적으로 C : \ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ RegAsm.exe에 있음)

이 부가 기능의 작동 방식

버튼을 사용하여 구성된 텍스트를 노란색 배경으로 대체하여 모든 DOM 트리를 통과합니다. 노란색 텍스트를 클릭하면 페이지에 동적으로 삽입 된 자바 스크립트 함수가 호출됩니다. 기본 단어는 ‘browser’이므로 많은 단어와 일치합니다!
편집 : 강조 표시 할 문자열을 변경 한 후 URL 상자를 클릭하고 Enter 키를 눌러야합니다 … F5가 작동하지 않습니다. F5가 ‘탐색’으로 간주되기 때문에 내비게이션 이벤트를 수신해야합니다. (아마도). 나중에 고치려고 노력하겠습니다.

이제 갈 시간입니다. 나는 매우 피곤하다. 궁금한 점은 언제든지 문의하십시오. 여행을 시작한 후 답변을받을 수 없을 수도 있습니다. 3 일 후에 돌아 왔지만 그 동안 여기에 오려고 노력할 것입니다.


답변

또 다른 멋진 접근법은 다음을 확인하는 것입니다.

http://www.crossrider.org

jquery를 사용하는 JS를 기반으로 한 프레임 워크이므로 단일 JS 코드를 사용하여 IE, FF 및 Chrome 용 브라우저 확장을 개발할 수 있습니다. 기본적으로 프레임 워크는 모든 불쾌한 작업을 수행하며 응용 프로그램 코드를 작성해야합니다.


답변

IE 확장의 상태는 실제로 매우 슬프다. IE5 Browser Helper Object의 오래된 모델 (예, 모두가 하루를 막고 싶어하는 악명 높은 BHO), 도구 모음 및 IE의 새로운 가속기가 있습니다. 그럼에도 불구하고 때때로 호환성이 깨질 수 있습니다. 나는 IE7과 헤어진 IE6의 확장을 유지하기 위해 사용되었으므로 변경된 것이 있습니다. 대부분 내가 아는 한 (수년간 BHO를 만지지는 않았지만) 여전히 Active Template Libraries (Microsoft COM의 STL과 같은 종류)를 사용하여 코딩해야하며 C ++ 전용입니다. C #으로 COM Interop을 수행하고 C #에서 수행하는 것을 피할 수는 있지만 가치가 너무 어려울 수 있습니다. 어쨌든,

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

그리고 IE8의 새로운 가속기의 경우 이것을 확인할 수 있습니다.

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

문서가 끔찍하고 API가 상당히 구식이라는 데 동의합니다. 여전히 이것이 도움이되기를 바랍니다.

편집 : 여기에 마지막 정보 소스를 던질 수 있다고 생각합니다. 나는 BHOs에서 일할 때 내 노트를 살펴보고있었습니다. 그리고 이것은 제가 그들과 함께 시작한 기사입니다. 그것은 오래되었지만 IE BHO (예 : IObjectWithSite)로 작업 할 때 사용할 ATL 인터페이스에 대한 좋은 설명이 있습니다. 나는 그것이 잘 설명되어 있고 그때 많은 도움을 받았다고 생각합니다.
http://msdn.microsoft.com/en-us/library/bb250436.aspx
또한 GregC가 게시 한 예를 확인했습니다. 그것은 적어도 IE8에서 작동하며 VS 2010과 호환되므로 C #을 원한다면 거기에서 시작하여 Jon Skeet ‘s Book을 볼 수 있습니다. (Depth 2nd edition의 C #) 13 장에는 COM과의 상호 작용을 개선하는 데 사용할 수있는 C # 4의 새로운 기능에 대한 많은 정보가 있습니다. (아직도 C ++에서 addin을 수행하는 것이 좋습니다)


답변

C # BHO 개발은 어려운 일입니다. 많은 icky COM 코드와 p / invoke 호출이 포함됩니다.

나는 대부분 완성 된 C # BHO here 을 가지고 있으며, 원하는대로 소스 를 자유롭게 사용할 수 있습니다. IE 보호 모드에서 appdata저장 하는 방법을 찾지 못했기 때문에 “주로” 라고 말합니다 .


답변

나는 몇 년 동안 IE의 웹 브라우저 컨트롤과 함께 일해 왔으며 그 과정에서 유용한 게시물과 함께 하나의 이름이 반복해서 등장합니다. Igor Tandetnik

확장 프로그램을 개발하는 경우 BHO를 타겟팅하고 인터넷 검색을 시작합니다.

BHO Igor Tandetnik

또는

브라우저 도우미 개체 Igor Tandetnik

그의 글은 종종 매우 상세하며, 자신이 무엇을 말하는지 알고 있습니다.

COM 및 ATL 프로그래밍에서 귀를 사로 잡을 수 있습니다. 샘플 연습은 다음을 확인하십시오.
http://msdn.microsoft.com/en-us/library/ms976373.aspx


답변

C # 4.0의 향상된 COM interop 기능인 Robert Harvey에 동의합니다. 재 작성이 절실히 필요한 오래된 C # 코드가 있습니다.

http://www.codeproject.com/KB/cs/Attach_BHO_with_C_.aspx

이것은 ATL을 피하고 Spartan COM을 사용하여 작업을 단순화하려는 시도입니다.

BHO를위한 C ++ 및 COM


답변

휠을 재발 명하지 않으려는 경우 Add In Express for IE를 사용해보십시오 . VSTO 물건에 제품을 사용 했으며 꽤 좋습니다. 또한 유용한 포럼과 빠른 지원을 제공합니다.