最近项目组需要实现一个对windows用户文件操作进行监控的功能,(也就是使用explorer资源管理器的操作),于是乎我就想到了使用Hook的方法进行拦截,查找一番资料后发现XP调用的是最简单的CopyFileEx, MoveFileWithProgressW, ReplaceFileW之类的API,所以XP是最好解决的,但是到了Vista及以后的系统中,微软采用了一种新的方法——com组件里的IID_IFileOperation接口类。这样的话就有点麻烦了,但是资料中也有人实现了对com组件的HOOK,是通过修改从com组件的虚表从而实现挂钩。因此,我也尝试了一下这种方法,就是Hook IFileOperation中的CopyItems/MoveItems/DeleteItem等接口从而实现对文件操作的监控。具体方法就下面给出。使用这种方法的过程中,我发现了一些问题,以至于我无法完全套用这种方法。问题如下:
- 通过Hook以上接口无法达到文件级的监控,就是说如果我选择了一个文件夹,然后对它进行复制或者剪切操作,则获取到的文件操作信息只有这个文件夹的路径和目的路径,至于文件夹里有什么,是否有套层,无从得知。PS:这个接口里是有个单数形式的CopyItem/MoveItem/DeleteItem的系列接口API,但是无论我怎么Hook他们,都不会被触发,也许是我使用的方法不对把,或者这几个API根本没有被调用。
- 通过以上接口我只能得到用户有该操作的意向,如果用户在过程中点击了取消,或者操作根本没有成功,我无从得知详情。
- 当遇到有文件名重复后得到新文件名时,我无法获取到准确的新文件名,因为接口所给的只有源路径和目的目录的路径(新文件路径还得我自己拚...),并没有更加详细的信息可以供我使用。
由于以上几种原因,我无法通过上述方法实现我想要的功能,所以我开始另辟蹊径,我认为windows应该还有更详细更底层一点的接口可以供我使用,经过多天的查找和尝试,我终于找到了一个符合我需求的接口IFileOperationProgressSink。
对于这个接口的描述我给出微软的说明:
Exposes methods that provide a rich notification system used by callers of IFileOperation to monitor the details of the operations they are performing through that interface.
意思应该是说这个接口是用来响应IFileOperation的各种操作和消息的,还能得到更为详细的操作信息。而在这个接口类中,有着许多我寻找了许久的API,比如PreCopyItem/PreMoveItem/PreDeleteItem以及PostCopyItem/PostMoveItem等等系列API,并且根据微软官方的说明,Pre前缀系列的API是指在操作进行前的消息处理,Post前缀的系列API是指在操作完成后所调用的处理函数。下面以CopyItem为例,给出微软的说明。