C#开发BHO插件UrlTrack

最近忽然突发奇想,想统计一下我最经常上的网站是哪些,并且在这些网站上都停留了多久。为此决定写一个BHO插件来做这件事。

BHO(Browser Help Objects)是实现了特定接口(IObjectWithSite)的COM组件。开发好的BHO插件除了要在注册表中注册为COM Server外,还必须将它的CLSID在HKLMSOFTWARE…Browser Helper Objects下注册为子键。每当浏览器[1]启动时,首先会在上述注册表位置查看是否有注册的BHO CLSID,如果有则分别创建一个实例,并对BHO实例进行初始化。BHO实例运行在浏览器的地址空间内,能对可访问的对象(如窗口、模块等等)执行任何 操作,且因为它依附于浏览器的主窗口,所以其生命周期与浏览器实例的生命周期一致。下图演示了BHO的创建过程:

下面就来介绍一下如何开发BHO插件。首先创建一个C#项目,类型为Class Library。然后将Class1.cs改名为IObjectWithSite.cs,还要给IObjectWithSite添加两个功能:GetSite和SetSite。

  1. PublicInterfaceIobjectwithsite
  2. {
  3. [Preservesig]
  4. IntSetsite([Marshalas(Unmanagedtype.Iunknown)]ObjectSite);
  5. [Preservesig]
  6. IntGetsite(RefGuidGuid,OutIntptrPpvsite);
  7. }

添加一个cs文件UrlTrack.cs,并且实现IObjectWithSite接口。使用BHO还需要添加两个引用SHDocVw.dll和MSHTML.dll,可以在WindowsSystem32目录下找到。

在IObjectWithSite.cs中,还需要为我们的程序指出IE的GUID,使得它可以挂接(attach)到IE上
[
ComVisible(true),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")
]

另外,还需要给BHO程序分配一个GUID,这个可以通过System.Guid.NewGuid()方法得到
[
ComVisible(true),
Guid("e90da13b-117a-4178-8111-0f712da09ff9"),
ClassInterface(ClassInterfaceType.None)
]

在UrlTrack.cs中,我们还需要写两个方法用来DLL注册和移除注册

  1. publicstaticstringBHOKEYNAME=@"SOFTWARE…BrowserHelperObjects";
  2. [ComRegisterFunction]
  3. publicstaticvoidRegisterBHO(Typetype)
  4. {
  5. RegistryKeyregistryKey=Registry.LocalMachine.OpenSubKey(BHO_KEY_NAME,true);
  6. if(registryKey==null)
  7. {
  8. registryKey=Registry.LocalMachine.CreateSubKey(BHO_KEY_NAME);
  9. }
  10. stringguid=type.GUID.ToString("B");
  11. RegistryKeybhoKey=registryKey.OpenSubKey(guid,true);
  12. if(bhoKey==null)
  13. {
  14. bhoKey=registryKey.CreateSubKey(guid);
  15. }
  16. //NoExplorer:dword=1preventstheBHOtobeloadedbyExplorer.exe
  17. bhoKey.SetValue("NoExplorer",1);
  18. bhoKey.Close();
  19. registryKey.Close();
  20. }
  21. [ComUnregisterFunction]
  22. publicstaticvoidUnregisterBHO(Typetype)
  23. {
  24. RegistryKeyregistryKey=Registry.LocalMachine.OpenSubKey(BHO_KEY_NAME,true);
  25. stringguid=type.GUID.ToString("B");
  26. if(registryKey!=null)
  27. registryKey.DeleteSubKey(guid,false);
  28. }

接下来就是实现具体的统计功能了。考虑一下,当输入网址后,我们需要记录下网址以及当前的时间;当在同一浏览窗口中切换网址时,不仅需要记录下网址 和当前时间,还要设置前一个浏览记录的结束时间;并且在关闭浏览器时,也要记下结束时间。所以在SetSite中需要挂载 NavigateComplete2和OnQuit事件。

  1. privatevoidNavigateComplete2(objectpDisp,refobjectURL)
  2. {
  3. stringurl=URLasstring;
  4. if(url.IndexOf("about:blank")>=0)
  5. {
  6. return;
  7. }
  8. if(visitHists.Count>0)
  9. {
  10. VisitHistcurrentHist=visitHists[visitHists.Count-1];
  11. if(currentHist.VisitUrl!=url)
  12. {
  13. currentHist.EndTime=System.DateTime.Now;
  14. }
  15. else
  16. {
  17. return;
  18. }
  19. }
  20. VisitHistnewHist=newVisitHist();
  21. newHist.StartTime=System.DateTime.Now;
  22. newHist.VisitUrl=url;
  23. visitHists.Add(newHist);
  24. }
  25. privatevoidOnQuit()
  26. {
  27. if(visitHists.Count>0)
  28. {
  29. VisitHistcurrentHist=visitHists[visitHists.Count-1];
  30. currentHist.EndTime=System.DateTime.Now;
  31. }
  32. //输出统计记录
  33. }

开始编译,然后就可以在bin目录下找到项目的dll文件了。在Console中使用regasm /codebase "UrlTrack.dll"注册dll。打开注册表,在HKLMSOFTWARE…Browser Helper Object可以看到多出了一个子项{E90DA13B-117A-4178-8111-0F712DA09FF9}。

需要注意的是,需要将AssemblyInfo.cs文件中的ComVisible属性设为true,否则在注册BHO时会得到这样的信息:
RegAsm : warning RA0000 : No types were registered.

更多的BHO资料可以看这里:Browser Extensions

[1] 在Windows操作系统上有两种浏览器:资源浏览器(explorer.exe,应用于文件系统)和Internet浏览器(IEXPLORE.EXE,应用于互联网资源)。

代码下载

你可能感兴趣的:(rack)