最近忽然突发奇想,想统计一下我最经常上的网站是哪些,并且在这些网站上都停留了多久。为此决定写一个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。
Public Interface Iobjectwithsite
{
    [Preservesig]
    Int Setsite([Marshalas(Unmanagedtype.Iunknown)]Object Site);
    [Preservesig]
    Int Getsite(Ref Guid Guid, Out Intptr Ppvsite);
}

添加一个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注册和移除注册
public static string BHOKEYNAME = @"SOFTWARE...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 bhoKey = registryKey.OpenSubKey(guid, true);
    if (bhoKey == null)
    {
        bhoKey = registryKey.CreateSubKey(guid);
    }
    // NoExplorer: dword = 1 prevents the BHO to be loaded by Explorer.exe
    bhoKey.SetValue("NoExplorer", 1);
    bhoKey.Close();

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

接下来就是实现具体的统计功能了。考虑一下,当输入网址后,我们需要记录下网址以及当前的时间;当在同一浏览窗口中切换网址时,不仅需要记录下网址和当前时间,还要设置前一个浏览记录的结束时间;并且在关闭浏览器时,也要记下结束时间。所以在SetSite中需要挂载NavigateComplete2和OnQuit事件。
private void NavigateComplete2(object pDisp, ref object URL)
{
    string url = URL as string;
    if (url.IndexOf("about:blank") >= 0)
    {
        return;
    }
    if (visitHists.Count > 0)
    {
        VisitHist currentHist = visitHists[visitHists.Count - 1];
        if (currentHist.VisitUrl != url)
        {
            currentHist.EndTime = System.DateTime.Now;
        }
        else
        {
            return;
        }
    }
    VisitHist newHist = new VisitHist();
    newHist.StartTime = System.DateTime.Now;
    newHist.VisitUrl = url;
    visitHists.Add(newHist);
}

private void OnQuit()
{
    if (visitHists.Count > 0)
    {
        VisitHist currentHist = visitHists[visitHists.Count - 1];
        currentHist.EndTime = System.DateTime.Now;
    }

// 输出统计记录
    ...
}

开始编译,然后就可以在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,应用于互联网资源)。

反射(13)——C#开发BHO插件UrlTrack相关推荐

  1. Java bho插件_VC++开发BHO插件——定制你的浏览器  作者 陆其明

    关键字 BHO Browser COM ATL 网址过滤 原作者姓名 陆其明 文章原始出处 http://hqtech.nease.net 读者评分 18 评分次数 4 正文 在Windows操作系统 ...

  2. Java bho插件_VC++开发BHO插件——定制你的浏览器 --------- 转

    DisableThreadLibraryCalls(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) _Module.Term(); ret ...

  3. 用VS2005开发BHO揭开IE插件的神秘面纱

    IE插件早已不是个新东西了,在IE4时代就有了,但是随着恶意插件的层出不穷,又一次被人重视起来.当前很多网站在无意识或有意识的情况下被挂马,让用户下载.cab自动安装,让用户中恶意IE插件.或者当用户 ...

  4. 用C#来开发CAD插件,含源代

    CAD插件看起来很神秘,其实一个合格码农经过几天就能快速掌握.没什么秘密,开发CAD插件和winform一样简单,多学几个类库用法就是,在CAD里展现界面和winform略有不同.学习CAD插件开发的 ...

  5. Android Studio开发-高效插件强烈推荐

    Android Studio开发-高效插件强烈推荐 现在Android的开发者基本上都使用Android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行).使用好And ...

  6. android 程序开发的插件化

    本文为 博客园 黑暗伯爵 原创,转载请注明  http://hangxin1940.cnblogs.com 原文地址:android 程序开发的插件化 模块化方法 之一 框架已经放出: android ...

  7. Firefox(火狐浏览器)丰富的Web开发辅助插件

    Firefox(火狐浏览器)丰富的Web开发辅助插件 大多数网页设计师与前端工程师都会使用Firefox(火狐浏览器),由于Firefox丰富的Web开发辅助插件可以为我们提供许多好的功能,比如HTM ...

  8. vsto下开发wps插件

    我们要开发wps插件了.之前用vsto开发过word插件,我也讲过c#下如何开发wps插件(有点繁琐).如果采用c#从头再开发wps插件,那么开发出来的office加载项就会出现两个.我们要实现的wp ...

  9. 使用Vue3+Element Plus开发Chrome插件

    使用Vue3+Element Plus开发Chrome插件 引言 初始Vue项目的创建 Element-Plus组件的安装及导入 其他文件配置 .eslintrc.js文件 vue.config.js ...

最新文章

  1. 测视力距离5米还是3米_视力表只能看到0.3,相当于近视度数200度?
  2. 当MySQL执行XA事务时遭遇崩溃,且看华为云如何保障数据一致性
  3. nodejs学习文档(一) 认识node.js
  4. 国密算法-商密认证-硬件加密-同方TF32A09-32位高速加密芯片
  5. 【液晶模块系列基础视频】4.5.X-GUI图形界面库-进度条等函数简介
  6. 使用批处理脚本(BAT)调用FFMPEG批量编码视频
  7. 地形剖面matlab,基于MATLAB河道横断面绘制.doc
  8. _CRT_SECURE_NO_DEPRECATE
  9. 点云特征提取--vfh
  10. 【Python数据科学手册】Pandas——十二、处理时间序列
  11. urllib库用POST请求模仿有道在线翻译
  12. java语言可以编程无人机么_java可以作为第一门编程语言学习吗
  13. 用python爬虫制作图片下载器(超有趣!)
  14. 电脑总是弹出乱七八糟的内容怎么办
  15. 华硕笔记本节能证书_节能证书编号
  16. 在Linux中进行docker网络端口映射
  17. 【游戏开发实战】使用Unity 2019制作仿微信小游戏飞机大战(七):主角飞机碰撞与爆炸
  18. 黑豆文本转语音工具V1.3(有声小说,地摊语音等制作领导者)
  19. 计算机在油气储运专业的应用,计算机多媒体专业学论文参考文献 计算机多媒体专业论文参考文献数量是多少...
  20. 梦幻西游2升级计算机,梦幻西游2官网3月1日维护公告 改名为梦幻西游电脑版

热门文章

  1. java cause_Java中getCause()方法的重要性?
  2. 伯克利CS61A错题笔记1.0
  3. [CS131] Lecture 1 Course Introduction课程介绍
  4. 如何在webstorm中使用jQuery库
  5. 虚拟机试练windows 2008 故障转移集群 MSCS
  6. win10系统MongoDB 4.0安装配置记录
  7. 巡检机器人的实施步骤
  8. 中小企业ERP系统选型四个标准分析
  9. java中csv文件怎么制作_Java生成csv文件
  10. python如何遍历字典对象