如何用filemon监控某个文件

购物网站系统源代码网页模板正式版

网上商城购物网站系统源代码,网上开店系统网页模板正式版,您还在为苦苦寻找一套适合的购物系统而烦恼吗您是否觉得单一色彩、風格的购物系统已经让您厌倦不堪?您是否想过只须用鼠标轻轻一点整站风格即会变幻无穷? 网络电子商务购物网站自助建站管理系统源码正式版 首次引入模板与以往程序大不相同,网店自助建站管理系统超漂亮正式版包括网站风格的商业模板模板风格变换无穷,颜銫、色调各不相同适合各行各业开店使用! 网络电子商务购物网站自助建站管理系统源码,网店自助建站管理系统超漂亮正式版,网上购物网站管理系统超漂亮正式版,由致力于电子商务网上购物网站自助建站管理系统正式版的开发助从事电子商务,网上销售购物的创业者成功网店自助建站管理系统超漂亮正式版,适合电脑,软件网络,办公设备,笔记本电脑电子商务商城专用配件,手机,通讯设备卡,移动聯通充值中心购物网站模板,购物网模板,购物网页模板,网上购物网站模板,网上购物模板,免费购物网站模板,购物系统模板,购物模板下载,购物网站模板下载,韩国购物网站模板,购物模板素材,购物车模板,php购物网站模板,网上购物系统,网上购物系统论文,网络购物系统,在线购物系统,免费购物系统,网域网络购物系统,asp购物系统,网域网上购物系统,购物车系统,asp网上购物系统,IP长途,数码相机摄像机,图形冲印,随身视听电子商务商城购粅系统音响,耳机,运动健身,运动明星网域商城购物系统,网上购物系统设计,网域购物系统,购物系统,网上购物系统下载,jsp网上购物系统,网仩商城购物系统,php购物系统,免费网上购物系统,网上购物系统流程图,电子购物系统,网上购物系统分析,购物系统论文,购物网站系统,在线购物系统概述,网上购物管理系统,购物系统下载,网上购物系统的设计,购物系统,网络购物系统论文,网上购物系统源码乐器,户外、军品电子商务商城购粅系统、旅游、机票,网络游戏虚拟商品交易区,电玩,动漫Cosplay,周边,居家日用装饰,文具园艺,邮币,古董电视购物系统,jsp购物系统,网上购粅系统,网域网络购物系统,网上购物系统源代码,商城购物系统,超市购物系统,购物系统模板,net网上购物系统,购物系统免费版,购物系统源码,网上购粅系统破解版, 网络电子商务购物网站自助建站管理系统源码,电子商务网上购物网站自助建站管理系统,网络时代,一个电子商务的时代,一个创慥财富奇迹的时候,你想建一个网上购物系统,网络购物系统,在线购物系统,商城购物系统 ,网络购物系统吗,你想用这个来创业吗? 购物系统电子商务购物网站自助建站管理系统,为你创造了软件的条件,本系统带购物车系统,asp语言编写的,最流行通用简单的购物系统,网上购物系统,利用SQL版电孓商务购物网站自助建站管理系统,建立一个专业的网上购物网站,网上购物系统,让你的客户在网上购物中心,进行网上购物,本系统是最好的网仩购物的网站,用本程序建立之网上购物网站大全,上海,北京,深圳,广州,香港,国外网上购物网站系统很多是在此基础上完成的,我们将打造最好,最夶的网上购物网站.你不用在搜索,网上购物网站模板,免费购物网站模板,韩国购物网站模板,欧美购物网站模板,购物网页模板,购物模板,购物模板丅载,网站模板,网站模板下载,因为本系统都已经为你做到了, 购物网源码,购物网站源码,购物车源码,asp购物车源码,jsp购物车源码,购物系统源码,asp购物车源码下载,asp.net购物车源码,网上购物源码,SQL版电子商务购物网站自助建站管理系统源码,你可以直接使用,更可以在此基础上修改,增加更多,更好的功能.洳不会本机调试本系统,请查看《IIS安装使用说明书》,本系统程序分电子商务购物网站管理系统通用版,清爽版,多风格版,sql数据库版. 网上购物系统功能,多用户购物系统,网域网上购物系统,网吧购物系统,网上购物系统 介绍,asp购物车系统,java网上购物系统,免费 网络购物系统,购物系统设计,网上购物系统意义,jsp购物车系统,电脑购物系统,网上购物系统的构建,购物系统 html,免费下载购物系统,简单购物系统,多用户网上购物系统,字画收藏,汽车,摩托自行车,家庭装修,五金工具网上购物系统在线购物系统,购物系统安防报警,个性定制,淘宝卖家服务珠宝首饰,流行饰品珠宝配件购物软件,电子商务购物电子商务商城购物,品牌手表,流行手表眼镜,彩妆,香水护肤,美体,女士箱包鞋帽,配件,女装奻士精品,男装asp免费购物系统,网上购物系统结构,淘宝购物系统,在线购物系统论文,asp简单购物系统,校园购物系统,网上购物系统的特点,asp,net 购物系统,网仩购物系统的发展,网上购物系统发展,网上购物系

  之前我花了一周时间研究攵档少得可怜的 ReadDirectoryChangesW。希望这篇文章可以为大家节约一些时间我相信我已经读过了我能找到所有相关文章和大量代码。几乎所有的例子包括微软自己的那个例子,都有明显缺陷或低级错误

  我曾在《Multithreading Applications in Win32》这本书中的某一章,介绍了同步IO激发态内核对象,重叠IOIO完成端口嘚区别。现在要谈的这个问题对我来说是小菜一碟。只不过上次写 重叠IO的痛苦折磨了我好多年这次应该也不会例外。

监控文件和目录嘚四种方式

  我们先看一下 SHChangeNotifyRegister这个函数通过窗口消息实现,所以需要一个窗口句柄它由Shell (Explorer)驱动,所以应用程序只会接收到 Shell 关心的通知這些通知很难满足你的需求。它仅仅对监控用户对Explorer的操作有用

  由于 SHChangeNotifyRegister 基于窗口消息,所以还会带来性能上的问题如果发生了太多文件变更,应用程序会不断接收到变更消息你必须自己确认实际发生的事情。对于一部分应用程序来说这实在是相当的囧。

  Windows 2000 引入了兩个新接口 和 。 FindFirstChangeNotification 很容易使用但没有给出变更文件的信息。即便如此这个函数对某些应用程序还是很有用的,比如传真服务和 SMTP 服务可鉯通过拖拽一个文件到一个目录来接受任务队列ReadDirectoryChangesW 会给出变更的内容和方式, 不过相对的,在使用上也更复杂一些

  同 SHChangeNotifyRegister 一样,这两个新函数也会有性能问题与 Shell 通知相比,它们的运行速度有明显提升但在不同目录间移动上千个文件仍然会导致你丢失一部分(或者很多)通知。丢失通知的原因很令人惊讶的是,似乎与你处理通知的速度有关

  Windows XP 引入了最终解决方案,可以跟踪每一个变更的细节即使你的軟件没有运行。很帅的技术但也相当难用。

  第四个同时也是最后一个解决方案需要安装,Sysinternals 的 FileMon 就使用了这种技术在 Windows 驱动开发包(WDK)中囿一个例子。这个方案本质上是一个如果没有正确的实现,有可能导致系统稳定性方面的问题

  对我来说,使用 ReadDirectoryChangesW在性能和复杂度仩会是一个很好的平衡。

  使用 ReadDirectoryChangesW 的最大挑战在于在IO模式,处理信号等待方式,以及线程模型这几个问题的整合上存在数百种可能性。如果你不是 Win32 I/O 方面的专家即使最简单的场景,你也很难搞定

  最后,当调用 ReadDirectoryChangesW 的时候你可以通过 flags 选择你要监控的内容,包括文件創建内容变更,属性变更等等你可以多次调用,每次一个 flag也可以在一次调用中使用多个 flag。多个 flag 总是正确的解决方案但如果你为了調试方便,需要一个 flag 一个 flag 的调用的话那就需要从 ReadDirectoryChangesW 返回的通知缓冲区中读取更多的数据。

  如果你的脑子正在囧的话那么你就能够明皛为什么那么多人都没法搞定这件事了。

  那么正确的答案是什么呢我的建议是:取决于你认为最重要的是什么。

  性能 - A4C6D4 - 性能最好嘚解决方案是使用I/O完成端口但是,这个激进的多线程方案实在太过复杂应当仅限在服务器上使用。对任何 GUI 程序来说这个方案似乎都昰不必要的。如果你不是一个多线程专家请远离这个策略。

  平衡 - A4C5D3 - 通过完成例程(Completion Routines)在一个线程中完成所有工作。你可以发起尽可能多嘚 ReadDirectoryChangesW 调用由于完成例程是自动分派的,所有不需要等待任何句柄你可以通过回调传递对象的指针,以便跟踪原始的数据结构

  起初峩曾经认为 GUI 程序可以通过 MsgWaitForMultipleObjectsEx 将变更通知混入到窗口消息中。但由于对话框有自己的消息循环当对话框显示的时候,通知便无法处理了于昰这个好主意被现实无情的碾碎了。

  在研究解决方案的时候我见识过各种用法:不靠谱的,错误的以及错得离谱的。

  如果你囸在使用上面提到的简单方案不要使用阻塞调用,因为唯一取消调用的方法是关闭句柄(未在文档中列出的方法)或者调用 Vista 之后的函数 。囸确的办法是使用触发式的同步I/O模式也就是等待目录句柄。结束线程的时候不要使用 TerminateThread,因为这个时候资源无法释放,从而导致各种各样的问题而是创建一个手动重置的 Event

  如果你有上千个目录需要监控,不要使用简单方案转换为平衡方案。或者监控公共的根目录并忽略不关心的文件。

  如果你需要监控整个驱动器请三思。你会接收到每个临时文件每个Internet缓存文件,每个应用程序数据变更的通知简单来说,大量的通 知会拖慢整个系统如果你需要监控整个驱动器,你应当使用变更日志(Change Journal)这样即使你的程序没有运行,也可以哏踪每一个变更绝对不要用 FILE_NOTIFY_CHANGE_LAST_ACCESS 标志监控整个驱动器。

  如果你使用了不带I/O完成端口的重叠I/O不要等待句柄,而是使用完成例程(Completion Routines)这样可鉯不受64个句柄的限制,可以让操作系统处理调用的分发还可以通过 OVERLAPPED 传递你自己的对象指针。等一下我会给出例子

  如果你使用了工莋线程,将结果传回给主线程的时候不要使用 SendMessage,而是使用 PostMessage如果主线程很繁忙,同步的 SendMessage 需要很久才能返回这就失去了使用工作线程的意义了。

  通过提供较大的缓冲区来尝试解决丢失通知的问题会是一个诱人的选项。但这不是明智的行为不管给定的缓冲区体积是哆少,内核的未分页内存池都 是分配相同大小的缓冲区如果你分配太大的缓冲区,有可能导致包括蓝屏在内的一系列问题感谢 MSDN 社区内嫆的匿名投稿人。

  现在我们来看看之前提到平衡方案的实现细节在 ReadDirectoryChangesW 的声明中,你会注意到第一个参数是一个目录的句柄你是否知噵你可以获得一个目录的句柄呢?名为OpenDirectory的函数是不存在 的CreateDirectory也不会返回句柄。第一个参数的文档是这样描述的:”这个目录必须以 FILE_LIST_DIRECTORY

 
  第┅个参数, FILE_LIST_DIRECTORY, 甚至没有在 中提到而是在中有一些没什么用的描述。
  类似的FILE_FLAG_BACKUP_SEMANTICS 有这样一行有趣的标注:“如果此标志没有与 SE_BACKUP_NAME 和 SE_RESTORE_NAME一起使用,仍然会进行适当的安全检查”在我过去的印象中,使用这个标志需要管理员权限这个标注证实了这一点。不管怎 样在 Windows Vista 系统中,如果啟用了 UAC调整安全令牌以启用这些权限的操作是不管用的。这里我不确定到底是要求改变了,还是文档有歧义其他类似的内容也令人困惑。
  共享模式也存在一个陷阱我看到一些例子没有使用 FILE_SHARE_DELETE。也许你认为目录不会被删除所以没有问题。但是这回导致其他进程無法重命名或者删除这个目录下的文件
  这个函数另一个潜在的陷阱在于,被引用的目录本身处于”使用中“的状态并且无法被删除。如果希望在监控目录的同时还允许目录被删除,你应当监控该目录的父目录及父目录下的文件和子目录
 
  实际调用 ReadDirectoryChangesW 是整个操作中朂简单的环节。如果你使用了完成例程唯一需要注意的就是缓冲区必须是DWORD对齐的。
  OVERLAPPED 结构体用来指定重叠操作但实际上 ReadDirectoryChangesW 没有使用结構体中的任何一个字段。关于完成例程这里有一个大家都知道的小技巧,就是你可以提供一个C++对象的指针文档是这么说 的:”OVERLAPPED 结构的嘚 hEvent 成员不会被系统使用,所以你可以按自己的方式使用“这意味着你可以将你自己对象的指针放进去。你可以在下面的示例代码中看到這一点:
 
  由于我们使用了重叠I/Om_Buffer直到完成例程被调用的时候才会填充。
 
  对于我们讨论的平衡方案有两个方法等待完成例程被调鼡。如果所有分派都使用完成例程那么只需要 SleepEx就可以。如果你需要在分派完成例程的同时等待句柄那么你需要使用 WaitForMultipleObjectsEx。这个函数的Ex版本偠求将线程置为 "alertable" 状态"alertable"状态指完成例程将要被调用。
  如果要结束使用SleepEx的线程你可以设置一个 SleepEx 循环中的标记,以退出SleepEx 循环如果调用唍成例程,你可以使用QueueUserAPC这个函数允许一个线程调用另一个线程中的完成例程。
 
  通知例程很简单只要读取数据并保存就可以了。真嘚是这样么错。完成例程的实现也有其复杂度
  首先,你需要检查并处理错误码 ERROR_OPERATION_ABORTED这个错误码意味着 CancelIo 被嗲用,这是最后的通知你需要做合适的清理工作。CancelIo的更多细节会在下一节描述在我的实现中,我使用 InterlockedDecrement 来减少 cOutstandingCalls 的值这个变量用来跟踪活动调用的计数,然后返回我的对象都由 MFC 框架进行管理,所以不需要再完成例程中释放
  你可以在单次调用中接收多个处理。务必遍历数据结构并挨个检查非空的 NextEntryOffset 字段
  ReadDirectoryChangesW 是一个 "W"例程,所以它使用Unicode这个例程没有 ANSI 版本。因此数据缓冲区自然也是Unicode。字符串不是 NULL 结尾的所以你不能使用 wcscpy。如果伱使用 ATL 或 MFC 的 CString 类你可以 用原始字符串加上给定的数字来实例化一个宽字符的CString
 
  最后,你必须在退出完成例程前重新发起 ReadDirectoryChangesW 的调用。你可鉯重用相同的 OVERLAPPED 结构体文档指出,在完成例程被调用后OVERLAPPED 结构体不会再次被 Windows使用。但是你必须确保缓冲区与当前调用使用的缓冲区不同,否则会遇到“竞态条件”
  有一点我不太清除,那就是在完成例程被调用和发起新的 ReadDirectoryChangesW 调用之间变更通知做了什么事情。
  我还必须重申如果很多文件在短时间发生变更,你有可能丢失通知根据文档描述,如果缓冲区溢出整个缓冲区的内容都会被丢 弃,lpBytesReturned会返囙0但是我不清除完成例程是否会将 dwNumberOfBytesTransfered 为 0 ,或者是否会将 dwNumberOfBytesTransfered 指定为错误码
  有几个关于完成例程错误实现的有趣例子。我最喜欢的一个是茬 上找到的那个家伙在喷完一个求助帖后,展示了他自己的完成例程实现并叫嚣:”这玩意看起来也不难嘛“。他 的代码漏掉了错误處理他没有处理 ERROR_OPERATION_ABORTED,没有处理缓冲区溢出他甚至没有重新发起 ReadDirectoryChangesW 调用。我觉得如果忽略了这些困难的事情,剩下的的确没什么难的。
 
  当你接受并解析一个通知时你需要确定如何处理它。这并不容易首先,你将经常接收到多个重复的变更通知特别是一个进程在寫入一个大文件时。如果要等待文件的写入完成你需要等待直到一段时候内都不再有文件更新之后,才能开始进行处理
   的一篇文嶂指出,FILE_NOTIFY_INFORMATION的文档有一个关键的描述:如果文件既有长文件名又有短文件名,那么文件会返回其中的一 个名字但不确定返回哪一个。大哆数时候在短文件名和长文件名之间转换都很容易,但是文件被删除后就不一样了。因此你必须维护一个跟踪文件的列表, 同时跟蹤长文件名和短文件名我无法在 Windows Vista 上重现这个行为,不过我只在一台计算机上做过尝试
  你有可能接收到你没有预料到的通知。例如即使你设置了 ReadDirectoryChangesW 的不接收子目录通知的参数,你仍然会接收到子目录本身的通知假设你有两个目录 C:\A 和 C:\A\B。你将文件 info.txt 从第一个目录移动到第②个目录你将会接收到 C:\A\info.txt 的 FILE_ACTION_REMOVED 通知,以及 C:\A\B 的
  令人惊讶的事情还会发生你是否使用过 NTFS 的硬链接?硬链接允许你将多个文件名引用同一个粅理文件如果你在一个目录中监控一个引用,在另一个目录中监控另一个引用当修改第二个目录中的文件时,会生成第一个目录的通知灰常的神奇。
  另一方面如果你使用Windows Vista引入的符号链接,被链接的文件不会生成通知仔细想想,也说得过去但是你得小心各种各样的可能性。
  还有第三种可能就是 Junction 从一个分区链接到另一个。这种情况下对子目录的监控不会监控被链接分区中的文件。这种荇为也说得通但是当发生在用户的机器上时,这种现象会令人感到困惑
 
  我没有找到任何文章和代码(即使在开源代码中)适当的清理了重叠调用。MSDN文档 指出通过调用 CancelIo 来取消重叠I/O这很容易。但是我的应用程序退出的时候会崩溃。堆栈显示我的某个第三方库正在將线程置为 'alertable' 状态(意即可以调用完成例程了),并且即使在我调用了CancelIo关闭了句柄,删除了 OVERLAPPED 结构体之后我的完成例程还是被调用了。
  于是我搜索了各种各样的关于调用 CancelIo 的网页我找到 中包含这样的代码:
 
  这个看起来很有希望成功,我信心满满得把这段代码拷贝到峩的程序中但是不管用。
  我再次查阅了 CancelIo 的文档其中指出,”所有被取消的I/O操作都会以ERROR_OPERATION_ABORTED 错误结束并且所有的I/O完成通知都会正常发苼。“换句话说在CancelIo被调用后,所有的完成例程都都至少会被调用最后一次对 SleepEx 的调用也本该允许,但不是这样子最后我认为,等待5毫秒太短了也许将"f"改成"while"就能解决这个问题了,但是这个方案要求轮询每一个重叠结 构体于是我选择了不同的方式。
  我最终的解决方案是跟踪未完成的请求数目然后持续调用 SleepEx 直到计数为0,在示例代码中关停的顺序如下:
 
  万一关停没有被合适的处理,主线程会根據一个超时时间等待工作线程结束如果工作线程没有顺利结束,我们就让 Windows 结束时干掉它
 
  ReadDirectoryChangesW 可以使用在网络驱动器上,当且仅当远程垺务器支持这个功能从基于Windows的计算机共享的目录可以正确的生成变更通知。 Samba 服务器则不会生成通知大概因为相关操作系统不支持这个功能。网络附加存储(NAS)设备通常运行Linux系统所以也不支持通知。至于高端存储域网络 (SANs)那就谁也说不准了。
  ReadDirectoryChangesW 当缓冲区长度大于 64 KB 並且程序监控网络上的一个目录时会失败并返回错误码 ERROR_INVALID_PARAMETER。这是因为相关的网络共享协议对包大小有限制
 
  如果你看到了这里,我要為你的"can-do"态度鼓掌希望你清晰的了解了如何使用ReadDirectoryChangesW,以及为什么要怀疑你看到的所有关于这个函数的示例代码仔细的测试很关键,也包括性能测试

Filemon—文件实时监控工具

4星(超过85%的資源)

版权声明:该资源内容由用户上传如若侵权请选择举报

身份认证VIP会员低至7折

一个资源只可评论一次,评论内容不能少于5个字

您会姠同学/朋友/同事推荐我们的CSDN下载吗

谢谢参与!您的真实评价是我们改进的动力~

我要回帖

 

随机推荐