监控Windows文件夹下面的文件(C#和C++实现)

最近在做虚拟打印机时,需要实时监控打印文件的到达,并移动文件到另外的位置。一开始我使用了线程,在线程里去检测新文件的到达。实际上Windows提供了一个文件监控接口函数ReadDIrectoryChangesW。这个函数可以对所有文件操作进行监控。

ReadDirectoryChangesW

函数声明

 1 BOOL ReadDirectoryChangesW(2   [in]                HANDLE                          hDirectory,3   [out]               LPVOID                          lpBuffer,4   [in]                DWORD                           nBufferLength,5   [in]                BOOL                            bWatchSubtree,6   [in]                DWORD                           dwNotifyFilter,7   [out, optional]     LPDWORD                         lpBytesReturned,8   [in, out, optional] LPOVERLAPPED                    lpOverlapped,9   [in, optional]      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
10 );

参数

hDirectory

指向要监听的目录句柄,必须使用FILE_LIST_DIRECTORY访问权限打开此目录。

lpBuffer

指向要读取DWORD对齐结果的格式化缓冲区的指针。该缓冲区的结构由FILE_NOTIFY_INFORMATION结构定义

nBufferLength

lpBuffer参数指向的缓冲区大小

bWatchSubtree

 指示是否以指定目录为根目录进行监控。

True:监视以指定目录为根的目录树

FALSE:仅监视指定目录

dwNotifyFilter

检查函数以确定等待操作是否满足过滤条件。此参数可以指定为以下的一个或多个

含义
FILE_NOTIFY_CHANGE_FILE_NAME监视目录或子树中的任何文件名更改(包括重命名、创建、删除文件)      
FILE_NOTIFY_CHANGE_DIR_NAME监视目录或子树中的任何目录名更改(包括重命名、创建、删除目录)
FILE_NOTIFY_CHANGE_ATTRIBUTES监视目录或子树中的任何属性更改
FILE_NOTIFY_CHANGE_SIZE  监视目录或子树中的任何文件大小更改(仅当文件写入磁盘时,操作系统才能检测到文件大小的更改)
FILE_NOTIFY_CHANGE_LAST_WRITE监视目录或子树中文件上次写入时间的任何更改(只有文件写入磁盘时,操作系统才会检测到最后写入时间的更改)
FILE_NOTIFY_CHANGE_LAST_ACCESS监视目录或子树中文件最后访问时间的任何更改
FILE_NOTIFY_CHANGE_CREATION监视目录或子树中文件创建时间的任何更改
FILE_NOTIFY_CHANGE_SECURITY监视目录或子树中任何安全描述符更改

lpBytesReturned

对于同步调用,此参数接收传输到lpBuffer参数中的字节数

lpOverlapped

指向OVERLAPPED结构的指针,提供在异步操作期间要用的数据,否则该值为NULL

lpConpletionRoutine

指向完成例程的指针,当操作已经完成或取消,并且调用线程处于可警告的等待状态时才会调用它

返回值

成功:不为0

失败:0

监控指定目录下的文件创建

假设我这里要监控D:\PrintFiles目录下的文件更改,操作如下:

打开目录,获取文件句柄

     // 打开目录, 获取文件句柄HANDLE hDirectory = ::CreateFile(L"D:\\PrintFiles", FILE_LIST_DIRECTORY,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS, NULL);if (INVALID_HANDLE_VALUE == hDirectory){return 0;}

调用ReadDirectoryChangesW监控文件夹

我这里只演示同步调用,异步调用可以参考MSDN文档。同步调用时,如果监控的目录未发生更改,会一直阻塞在那里。

      DWORD dwRet = 0;DWORD dwBufferSize = 2048;BYTE* pBuf = new BYTE[dwBufferSize];FILE_NOTIFY_INFORMATION* pFileNotifyInfo = (FILE_NOTIFY_INFORMATION*)pBuf;BOOL bRet = ReadDirectoryChangesW(hDirectory,pFileNotifyInfo, dwBufferSize,TRUE,FILE_NOTIFY_CHANGE_FILE_NAME|           //修改文件名FILE_NOTIFY_CHANGE_ATTRIBUTES |         // 修改文件属性FILE_NOTIFY_CHANGE_LAST_WRITE,          // 最后一次写入&dwRet,NULL, NULL);

输出结果

  if (FALSE == bRet){DWORD dwError = GetLastError();std::cout << "ReadDirectoryChangesW failed - " << dwError << std::endl;}std::wcout.imbue(std::locale("chs"));//判断操作类型switch (pFileNotifyInfo->Action){case FILE_ACTION_ADDED:std::wcout << "Create file " << pFileNotifyInfo->FileName << std::endl;break;default:break;}CloseHandle(hDirectory);delete[] pBuf;

运行效果

System.IO.FileSystemWatcher类

在C#中,可以使用 System.IO.FileSystemWatcher类来进行监听。它内部也是调用了ReadDirectoryChangesW API函数

监控文件的行为定义在System.IO.NotifyFilters

 1    [Flags]2     public enum NotifyFilters3     {4         FileName = 0x1,5         DirectoryName = 0x2,6         Attributes = 0x4,7         Size = 0x8,8         LastWrite = 0x10,9         LastAccess = 0x20,
10         CreationTime = 0x40,
11         Security = 0x100
12     }

在C#中是通过事件订阅的形式来进行通知的。

C#进行了再次封装,所以会比直接在C++中使用要方便一些。创建监听后,只需要等待事件触发就行了。

FileSystemWatcher使用方法如下:

              FileSystemWatcher systemWatcher = new FileSystemWatcher();systemWatcher.Path = this.textBox1.Text;//设置监听的行为//这里设置为文件名systemWatcher.NotifyFilter = NotifyFilters.FileName;//设置文件类型过滤systemWatcher.Filter = "*.txt";systemWatcher.Changed += (obj, args) => { ShowMsg($"文件更改{args.Name}"); };systemWatcher.Created += (obj, args) => { ShowMsg($"文件创建{args.Name}"); };systemWatcher.Deleted += (obj, args) => { ShowMsg($"文件删除{args.Name}"); };systemWatcher.Renamed += (obj, args) => { ShowMsg($"文件重命名{args.Name}"); };//开始监听systemWatcher.EnableRaisingEvents = true;    

运行效果

示例代码

参考资料:

ReadDirectoryChangesW function (winbase.h) - Win32 apps | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3269298.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

1 深度学习网络DNN

代码来自B站up爆肝杰哥 测试版本 import torch import torchvisiondef print_hi(name):print(fHi, {name}) if __name__ __main__:print_hi(陀思妥耶夫斯基)print("HELLO pytorch {}".format(torch.__version__))print("torchvision.version:", torchvi…

2024后端开发面试题总结

一、前言 上一篇离职贴发布之后仿佛登上了热门&#xff0c;就连曾经阿里的师兄都看到了我的分享&#xff0c;这波流量真是受宠若惊&#xff01; 回到正题&#xff0c;文章火之后&#xff0c;一些同学急切想要让我分享一下面试内容&#xff0c;回忆了几个晚上顺便总结一下&#…

mybatis查询数据字段返回空值

1.描述 数据苦衷实际存储字段全不为空 查询后brand_name/company_name为空 2.原因分析 带下划线的字段&#xff0c;都会返回空值&#xff0c;应该是字段映射出了问题 3.解决方案 在配置文件中添加下划线自动映射为驼峰 <configuration><settings><sett…

【计算机网络】OSPF单区域实验

一&#xff1a;实验目的 1&#xff1a;掌握在路由器上配置OSPF单区域。 2&#xff1a;学习OSPF协议的原理&#xff0c;及其网络拓扑结构改变后的变化。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS交换机、网线、内网网卡接口、Windows 2019操作系统的计算机等。…

STM32+ESP8266-连接阿里云-物联网通用Android app(2)

前言 接着上一篇的文章创建好了设备&#xff0c;云产品转发&#xff0c;让STM32连接上阿里云&#xff0c;发布和订阅了相关主题。本篇文章来编写一个Android app来进行控制STM32和接收传感器数据显示在屏幕上。基于Android studio。 演示视频 实现一个简单的app来控制stm32开…

Django-3.3创建模型

创建模型&#xff08;models&#xff09;的时候&#xff0c; 1&#xff1a;我们需要这个模型是哪个文件下面的模型&#xff08;models&#xff09;&#xff0c;我们需要在配置文件中吧应用安装上&#xff08;安装应用&#xff1a;INSTALLED_APPS&#xff09; 2&#xff1a;找对…

【机器学习】不同操作系统下如何安装Jupyter Notebook和Anaconda

引言 Jupyter Notebook 是一个非常流行的开源Web应用程序&#xff0c;允许你创建和共享包含代码、方程、可视化和解释性文本的文档 文章目录 引言一、如何安装Jupyter Notebook1.1 对于Windows用户1.2 对于macOS用户1.3 对于Linux用户&#xff1a; 二、如何安装Anaconda2.1 对于…

《python程序语言设计》第6章13题 数列求和编写一个函数计算

正确代码 def sumNumber(integer_num):print(" i || m(i)")print("-"*30)a 0for i in range(1, integer_num 1):a i / (i 1)print("{:4d} || {:.4f}".format(i, a))sumNumber(20)结果如下

使用 leanback 库 GridView 管理AnroidTV的焦点

一、前情提要 我当前需要开发一个TV应用&#xff0c;但是之前处理过的焦点问题的很少&#xff0c;现在空下来了&#xff0c;对过往的工作做一个总结分享。在手机APP开发中常用的 RecycleView 在 TV 中开发时&#xff0c;无法解决大量的焦点问题&#xff0c;所以使用leanback进…

ElasticSearch核心之DSL查询语句实战

什么是DSL&#xff1f; Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。 DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。目前常用的框架查询方法什么的底层都是构建DSL语句实现的&#xff0c;所以你必…

git 学习总结

文章目录 一、 git 基础操作1、工作区2、暂存区3、本地仓库4、远程仓库 二、git 的本质三、分支git 命令总结 作者: baron 一、 git 基础操作 如图所示 git 总共有几个区域 工作区, 暂存区, 本地仓库, 远程仓库. 1、工作区 存放项目代码的地方&#xff0c;他有两种状态 Unm…

2024新版 黑马程序员《C++零基础入门》笔记——第一章24 三元运算符

1.三元运算符 2.代码实践 #include "iostream" using namespace std;int main() {// 表达式? v1 : v2;int num1, num2;cout << "请输入num1的值" << endl;cin >> num1;cout << "请输入num2的值" << endl;cin >…

Flink-CDC解析(第47天)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. CDC 概述1.1 什么是CDC&#xff1f;1.2 CDC的实现机制1) 基于主动查询的 CDC&#xff1a;2) 基于事件接收CDC&#xff1a; 前言 本文主要概述了Flink-CDC. …

万界星空科技灯具行业MES系统:点亮生产管理的未来

在快速迭代的灯具行业中&#xff0c;高效、精准的生产管理是企业保持竞争力的关键。万界星空科技推出的灯具行业MES&#xff08;制造执行系统&#xff09;系统&#xff0c;以其强大的功能和完善的管理体系&#xff0c;正成为众多灯具生产企业的首选解决方案。本文将重点介绍万界…

u盘文件删除如何恢复?u盘恢复数据的8个诀窍,新手必看!

随着互联网的普及&#xff0c;u盘已成为人手必备的一个工具&#xff0c;承载着我们许多的重要文件和数据。然而&#xff0c;当意外删除或丢失这些关键数据时&#xff0c;我们常常会感到无助。您是否也曾经面对过u盘文件误删的尴尬吗&#xff1f;亦或者是否曾为如何从u盘中恢复已…

【漏洞复现】phpStudy 小皮 Windows面板 存在RCE漏洞

靶场资料后台自行领取【靶场】 image-20240726092307252 PhpStudy小皮面板曝RCE漏洞&#xff0c;本质是存储型XSS引发。攻击者通过登录用户名输入XSS代码&#xff0c;结合后台计划任务功能&#xff0c;实现远程代码执行&#xff0c;严重威胁服务器安全。建议立即更新至安全版…

Study--Oracle-07-ASM相关参数(四)

一、ASM主要进程 1、ASM主要后台进程 ASM实例除了传统的DBWn、LGWR、CKPT、SMON和PMON等进程还包含如下几个新后台进程: 2、牛人笔记 邦德图文解读ASM架构,超详细 - 墨天轮 二、数据库实例于ASM实例之间的交互关系 数据库实例与ASM实例之间的交互关系涉及多个步骤和过程,…

ICML最佳论文SD3上线公共教程!DreamBench++图像自动评估新基准来了,实现人类偏好深度对齐

近日&#xff0c;ICML 2024 最佳论文公布了&#xff01;其中就包含年度图像生成的「网红模型」——Stable Diffusion 3&#xff08;简称 SD3&#xff09;。SD3 是由 Stability AI 开发的最新文本到图像生成模型&#xff0c;前段时间已经全网开源&#xff01;HyperAI 超神经现已…

【PyCharm】PyCharm 2024.1 的最新变化-代码补全与智能提示

目录 代码补全与智能提示 更智能的代码补全功能 基于机器学习的代码建议 上下文相关的代码片段推荐 全行代码补全支持 (JavaScript 和 TypeScript) 本地 ML 模型的全行补全 示例 示例 1: 基于上下文的代码建议 示例 2: 全行代码补全 详细对比示例 示例 3: 传统代码补…

【iOS】3G share仿写

3G share 前言登录、注册界面首页搜索搜索更换照片折叠cell 文章活动我的 前言 本周进行了3G share的仿写&#xff0c;这个仿写内容较多&#xff0c;用到了很多之前学习的东西&#xff0c;也学习了许多的新知识。 登录、注册界面 这两个界面主要运用属性传值和协议传值&…