使用托管代码进行 BHO 开发
如何使用 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.dll 和 MSHTML.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)。我们还将向类中添加两个变量:WebBrowser
和 HTMLDocument
。
在 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 还有很长的路要走。让我们一起期待最好的结果。
请不要忘记留下您的评论……………..