栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何开始开发Internet Explorer扩展?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何开始开发Internet Explorer扩展?

[更新]我正在更新此答案,以在带有 Visual Studio 2017社区的* Windows 10 x64中 使用 Internet
Explorer 11
。此答案的先前版本(对于Internet Explorer 8,在Windows 7 x64和Visual Studio
2010中)在此答案的底部。
***

创建有效的Internet Explorer 11加载项

我使用 的Visual Studio 2017年的社区C#.Net框架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 Studio2017CommunityCommon7ToolsVsDevCmd.bat"cd "%ProgramFiles(x86)%Microsoft Visual Studio2017CommunityCommon7IDEPublicAssemblies"regasm Microsoft.mshtml.dllgacutil /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    }}

互操作

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.Unipre)]    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
。将按钮的 DialogResult 设置为
Ok 。将此代码放在表单代码中:

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 Exploreriexplore.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” /取消注册“ $(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 Tools  **x64 ** gacutil.exe

64位IE 需要64位编译和64位注册的BHO。尽管我只能使用32位IE11进行调试,但是32位注册扩展也可以通过运行64位IE11来工作。

这个答案似乎对此有一些附加信息:https :
//stackoverflow.com/a/23004613/195417

如果需要,可以使用64位重装:

%windir% Microsoft.NET  framework **64 ** v4.0.30319  RegAsm.exe

此加载项如何工作

我没有更改加载项的行为。。。下面介绍一下IE8部分。


## IE8的先前答案

伙计…这是很多工作!我很好奇如何做到这一点,以至于我自己做了。

首先…信誉不全是我的。这是我在以下网站上发现的内容的汇总:

  • CodeProject文章,如何制作BHO;
  • 15秒,但它不是15秒,花了大约7个小时;
  • Microsoft教程,帮助我添加了命令按钮。
  • 这个social.msdn主题帮助我弄清楚该程序集必须在GAC中。
  • 此MSDN博客文章包含一个完整的示例
  • 许多其他网站,在发现过程中…

当然,我希望我的答案具有您要求的功能:

  • DOM遍历以查找某些内容;
  • 显示窗口的按钮(以我为例进行设置)
  • 保留配置(我将为此使用注册表)
  • 最后执行javascript。

我将逐步介绍它,以及如何在 Windows 7 x64中* 使用 Internet Explorer 8 进行 管理
…请注意,我无法在其他配置中进行测试。希望你理解=)
*

创建有效的Internet Explorer 8加载项

我使用的是 Visual Studio 2010C#4.Net framework 4
,因此其中一些步骤可能对您略有不同。

创建了一个类库。我叫我 InternetExplorerExtension

将这些引用添加到项目中:

  • 互操作
  • 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.0Common7IDEPrivateAssembliesInterop.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;...

互操作

与IE11版本相同。

最后是表格,我们将使用它来配置选项。在此表格中,放置a

TextBox
和Ok
Button
。将按钮的 DialogResult 设置为
Ok 。该代码与IE11插件相同。

在项目属性中,执行以下操作:

  • 用强力钥匙在组件上签名;
  • 在“调试”选项卡中,将“ 启动外部程序” 设置为
    C:Program Files (x86)Internet Exploreriexplore.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” /取消注册“ $(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树,用黄色背景本身替换使用按钮配置的文本。如果单击发黄的文本,它将调用动态插入页面的javascript函数。默认单词是“浏览器”,因此它与很多单词匹配!
编辑:
更改要突出显示的字符串后,您必须单击URL框,然后按Enter键。F5将不起作用,我认为这是因为F5被视为“导航”,并且需要收听导航事件(也许)。我稍后将尝试解决。

现在,该走了。我很累。随便问问题…也许是因为我要去旅行而无法回答…三天后我会回来,但在此期间我会尽量来这里。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/442817.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号