65.9K
CodeProject 正在变化。 阅读更多。
Home

使用托管代码进行 BHO 开发

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (9投票s)

2012年3月19日

CPOL

4分钟阅读

viewsIcon

56362

如何使用 C# 创建一个简单的 BHO。

引言

浏览器帮助对象 (BHO) 是 Internet Explorer (IE) 的一个插件。BHO 允许开发人员控制 IE。插件是一种扩展浏览器功能的程序。它可以用于检索信息或修改浏览器窗口中显示的网页内容,或者仅用于为用户提供在工具栏中查看当日股市行情或天气的功能。

背景 

开始 BHO 开发一开始可能会令人沮丧,需要学习所有这些东西。作为一名初学者,我想与其他初学者分享我的经验。在这里,我将解释 BHO 的简单实现。

浏览器帮助对象是一个为每个 IE 窗口加载的 COM 对象。当浏览器窗口打开时,它会创建 BHO 的副本;当窗口关闭时,它会销毁 BHO 的副本。您需要一个与浏览器交互的 COM DLL。这可以通过在类中实现 IObjectWithSite 来完成。我们需要使用 COM 互操作库在我们的 .NET 项目中实现 COM DLL。

在编写 C# 代码时,我们还需要自己编写 IObjectWithSite 接口。然后,我们还需要在 BHO 中实现该接口。为了与 HTML 文档交互,我们需要添加对 Microsoft.mshtml 库的引用,并获取浏览器中的 DOM 或当前网页,我们需要将 SHDocVw 库添加为引用。此外,我们还需要添加两个函数,它们将使用密钥将我们的 COM 组件注册(和取消注册)为 Internet Explorer 的 BHO。

向 BHO 开发世界问好: 

让我们创建一个关于 BHO 的“Hello world”项目。启动一个新的 C# 类库项目。我将其命名为“HelloBHOWorld”。 

将“Class1.cs”重命名为“IObjectWithSite.cs”。 

在类中添加 'using System.Runtime.InteropServices;'。我们需要在此类下实现 'IObjectWithSite' 接口,还需要添加 'GetSite' 和 'SetSite' 两个函数。要了解有关此接口的更多信息,请参阅 http://msdn2.microsoft.com/en-us/library/Aa768220.aspx

IObjectWithSite 成员

GetSite获取使用 IObjectWithSite::SetSite 设置的最后一个站点。如果没有已知的站点,对象将返回一个失败代码。
SetSite将站点的 IUnknown 指针提供给对象。

IObjectWithSite.cs 下,我们需要为我们的程序指定 IE 的 GUID,以便它可以附加到 IE。代码片段应如下所示:

using System.Runtime.InteropServices;
namespace HelloBHOWorld
{
    //GUID reference of IF
    [
    ComVisible(true),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
    Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")
    ]
    //Declaration of the interface
    publicinterfaceIObjectWithSite
    {
        [PreserveSig]
        int SetSite([MarshalAs(UnmanagedType.IUnknown)]object site);
        [PreserveSig]
        int GetSite(refGuid guid, outIntPtr ppvSite);
    }
}

我们已经完成了 IObjectWithSite.cs。现在我们需要添加另一个名为 BHO.cs 的类文件。在那里添加一个 BHO 类。正如我们之前提到的,我们需要两个引用,SHDocVw.dllMSHTML.dll。SHDocVw 是 Microsoft Shell Document Object and Control Library。MSHTML 是用于访问动态 HTML (DHTML) 对象模型的接口,这些接口基于 IDispatch ,并且是访问脚本也使用的对象模型的依据。要了解更多信息,请参阅: http://msdn2.microsoft.com/en-us/library/bb498651.aspx

让我们添加它们,


我们将使用消息框来显示信息,因此我们需要添加另一个引用,

我们需要在 BHO.cs 文件下添加以下引用:

using SHDocVw;
using mshtml;
using System.IO;
using Microsoft.Win32;
using System.Runtime.InteropServices;

稍后我们将定义这两个方法,我们将在 BHO 类中实现该接口。

我们需要在 BHO.cs 下为我们自己的程序分配一个 GUID。我们可以使用 System.Guid.NewGuid() 方法获取一个新的密钥(我有一个小工具可以生成 GUID)。我们还将向类中添加两个变量:WebBrowserHTMLDocument

BHO.cs 文件中,我们需要编写两个函数来注册/取消注册此 DLL。

public static string BHO_KEY_NAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
    RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHO_KEY_NAME, true);
    if (registryKey == null)
        registryKey = Registry.LocalMachine.CreateSubKey(BHO_KEY_NAME);
    string guid = type.GUID.ToString("B");
    RegistryKey ourKey = registryKey.OpenSubKey(guid);
    if (ourKey == null)
        ourKey = registryKey.CreateSubKey(guid);
    ourKey.SetValue("Alright", 1);
    registryKey.Close();
    ourKey.Close();
}

[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
    RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHO_KEY_NAME, true);
    string guid = type.GUID.ToString("B");
    if (registryKey != null)
    registryKey.DeleteSubKey(guid, false);
}

在这里,我们将使用 OnBeforeNavigate() 方法从浏览器检索信息。'OnBeforeNavigate' 在 Web 浏览器发生导航之前调用一个事件。要了解更多信息,请参阅, http://msdn.microsoft.com/en-us/library/2chzz53b.aspx

接下来,我们将编写 OnBeforeNavigate 方法的主体,并定义 'SetSite' 和 GetSite' 方法。在 'SetSite' 方法中,我们为 OnBeforeNavigate 函数编写事件处理程序。

public void OnBeforeNavigate2(object pDisp, ref object URL, refobject Flags, 
       ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
}
#region IObjectWithSite Members
public int SetSite(object site)
{
    if (site != null)
    {
        webBrowser = (WebBrowser)site;
        webBrowser.BeforeNavigate2 += new
        DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
    }
    else
    {
        webBrowser.BeforeNavigate2 -= new
        DWebBrowserEvents2_BeforeNavigate2EventHandler(this.OnBeforeNavigate2);
        webBrowser = null;
    }
    return 0;
}

public int GetSite(ref Guid guid, out IntPtr ppvSite)
{
    IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
    int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
    Marshal.Release(punk);
    return hr;
}
#endregion

例如,我们为 'OnBeforeNavigate2' 方法编写一些代码。此代码将跟踪站点的输入字段,并显示输入字段的名称和值。

public void OnBeforeNavigate2(object pDisp, ref object URL, ref object Flags, 
       ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
{
    document = (HTMLDocument)webBrowser.Document;
    System.Windows.Forms.MessageBox.Show("URL to redirect: " + URL.ToString());
    foreach (IHTMLInputElement tempElement in document.getElementsByTagName("INPUT"))
    {
        System.Windows.Forms.MessageBox.Show(tempElement.name + " = " + tempElement.value);
    }
}

注册和取消注册 BHO

要注册/取消注册 BHO,我们使用 'RegAsm.exe' 并编写批处理文件 'registercom.bat' 和 'unregisterall.bat'

REM register for com so we can test the register/unregister functions while debugging
regasm.exe /codebase "HelloBHOWorld.dll"
pause
REM unregister HelloBHOWorld.dll for COM
regasm.exe /unregister "HelloBHOWorld.dll"
pause

运行 'registercom.bat' 文件

现在打开 IE 浏览器,进入“工具”>“管理加载项…”您应该会在列表中看到您的 BHO

现在浏览任何站点(google.com),在框中输入文本并单击按钮。您应该会看到:

所以这可以是您的第一个 IE 插件。这仅仅是个开始,编写专业的 BHO 还有很长的路要走。让我们一起期待最好的结果。

请不要忘记留下您的评论……………..

© . All rights reserved.