ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)(文件被修改了,也可以探测到)
- // .h文件
- #pragma once
- typedef void (*PFN_NotifyAction)(DWORD dwAction, LPWSTR szFile, DWORD dwLength);
- class CDirectoryWatch
- {
- public:
- CDirectoryWatch(void);
- virtual ~CDirectoryWatch(void);
- public:
- BOOL StartDirectoryWatch(LPCTSTR lpszDirectory, PFN_NotifyAction pFn_NotifyAction);
- BOOL StopDirectoryWatch(void);
- private:
- static UINT __cdecl ThreadProc(LPVOID lParam);
- static UINT __cdecl DirectoryWatch(LPVOID lParam);
- private:
- HANDLE m_hFile;
- CWinThread* m_pThread;
- TCHAR m_szDirectory[MAX_PATH];
- };
- // .cpp文件
- #include "StdAfx.h"
- #include "DirectoryWatch.h"
- #include <strsafe.h>
- typedef enum
- {
- MSG_STARTWATCH = (WM_USER + 0x11),
- MSG_STOPWATCH,
- MSG_EXITTHREAD
- };
- #define MAX_BUFFER_SIZE (1024)
- typedef struct _tagWATCHPARAMETERS
- {
- _tagWATCHPARAMETERS()
- {
- hFile = INVALID_HANDLE_VALUE;
- hEvent = NULL;
- memset(&ol, 0, sizeof(OVERLAPPED));
- pBuffer = NULL;
- dwBufferSize = 0;
- bExit = FALSE;
- pFn_NotifyAction = NULL;
- }
- HANDLE hFile;
- HANDLE hEvent;
- OVERLAPPED ol;
- BYTE* pBuffer;
- DWORD dwBufferSize;
- BOOL bExit;
- PFN_NotifyAction pFn_NotifyAction;
- }WATCH_PARAMETERS, *PWATCH_PARAMETERS;
- CDirectoryWatch::CDirectoryWatch() : m_hFile(INVALID_HANDLE_VALUE), m_pThread(NULL)
- {
- memset(m_szDirectory, 0, sizeof(m_szDirectory));
- m_pThread = AfxBeginThread(ThreadProc, NULL, 0, CREATE_SUSPENDED, 0, NULL);
- if(NULL == m_pThread)
- {
- TRACE("Error Code : %d\n", GetLastError());
- return ;
- }
- m_pThread->m_bAutoDelete = FALSE;
- m_pThread->ResumeThread();
- }
- CDirectoryWatch::~CDirectoryWatch()
- {
- if(INVALID_HANDLE_VALUE != m_hFile)
- {
- CloseHandle(m_hFile);
- m_hFile = INVALID_HANDLE_VALUE;
- }
- if((NULL != m_pThread) && (NULL != m_pThread->m_hThread))
- {
- m_pThread->PostThreadMessage(MSG_EXITTHREAD, 0, 0);
- WaitForSingleObject(m_pThread->m_hThread, INFINITE);
- delete m_pThread;
- m_pThread = NULL;
- }
- }
- BOOL CDirectoryWatch::StartDirectoryWatch(LPCTSTR lpszDirectory, PFN_NotifyAction pFn_NotifyAction)
- {
- if(NULL == m_pThread)
- {
- return FALSE;
- }
- if(NULL == lpszDirectory)
- {
- return FALSE;
- }
- if(NULL == pFn_NotifyAction)
- {
- return FALSE;
- }
- if(!PathFileExists(lpszDirectory))
- {
- TRACE("Error Code : %d\n", GetLastError());
- return FALSE;
- }
- if(!PathIsDirectory(lpszDirectory))
- {
- TRACE("Error Code : %d\n", GetLastError());
- return FALSE;
- }
- if(0 == _tcslen(m_szDirectory))
- {
- StringCchPrintf(m_szDirectory, _countof(m_szDirectory), _T("%s"), lpszDirectory);
- }
- else if(CSTR_EQUAL != CompareStringOrdinal(m_szDirectory, -1, lpszDirectory, -1, TRUE))
- {
- TRACE("Not Change Directory.\n");
- return FALSE;
- }
- if(INVALID_HANDLE_VALUE == m_hFile)
- {
- m_hFile = CreateFile(lpszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
- if(INVALID_HANDLE_VALUE == m_hFile)
- {
- TRACE("Error Code : %d\n", GetLastError());
- return FALSE;
- }
- }
- return m_pThread->PostThreadMessage(MSG_STARTWATCH, (WPARAM)m_hFile, (LPARAM)pFn_NotifyAction);
- }
- BOOL CDirectoryWatch::StopDirectoryWatch()
- {
- if(NULL != m_pThread)
- {
- return m_pThread->PostThreadMessage(MSG_STOPWATCH, 0, 0);
- }
- return FALSE;
- }
- UINT __cdecl CDirectoryWatch::DirectoryWatch(LPVOID lParam)
- {
- WATCH_PARAMETERS* pParam = (WATCH_PARAMETERS*)lParam;
- if(NULL == pParam)
- {
- return 0;
- }
- HANDLE& hFile = pParam->hFile;
- BYTE* pBuffer = pParam->pBuffer;
- DWORD dwBufferSize = pParam->dwBufferSize;
- OVERLAPPED& ol = pParam->ol;
- HANDLE& hEvent = pParam->hEvent;
- BOOL& bExit = pParam->bExit;
- PFN_NotifyAction pFn_NotifyAction = pParam->pFn_NotifyAction;
- DWORD dwBytesReturn = 0;
- DWORD dwRet = WAIT_FAILED;
- DWORD dwOffSet = 0;
- TCHAR szFile[MAX_PATH] = {0};
- while(TRUE)
- {
- if(WAIT_OBJECT_0 != WaitForSingleObject(hEvent, INFINITE))
- {
- TRACE("Error Code : %d\n", GetLastError());
- break;
- }
- if(bExit)
- {
- break;
- }
- if(!ReadDirectoryChangesW(hFile, pBuffer, dwBufferSize, TRUE,
- 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, &dwBytesReturn, &ol, NULL))
- {
- TRACE("Error Code : %d\n", GetLastError());
- break;
- }
- if(!GetOverlappedResult(hFile, &ol, &dwBytesReturn, TRUE))
- {
- TRACE("Error Code : %d\n", GetLastError());
- break;
- }
- FILE_NOTIFY_INFORMATION* pFileNotify = (FILE_NOTIFY_INFORMATION*)pBuffer;
- do
- {
- if(pFn_NotifyAction && (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 0)))
- {
- pFn_NotifyAction(pFileNotify->Action, pFileNotify->FileName, (pFileNotify->FileNameLength) / sizeof(WCHAR));
- }
- dwOffSet = pFileNotify->NextEntryOffset;
- pFileNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pFileNotify + dwOffSet);
- } while (dwOffSet);
- }
- TRACE0("DirectoryWatch Thread Exit ... \n");
- return 0;
- }
- UINT __cdecl CDirectoryWatch::ThreadProc(LPVOID lParam)
- {
- WATCH_PARAMETERS* pParam = new WATCH_PARAMETERS;
- if(NULL == pParam)
- {
- goto __CLEANUP__;
- }
- BYTE* pBuffer = new BYTE[MAX_BUFFER_SIZE];
- if(NULL == pBuffer)
- {
- goto __CLEANUP__;
- }
- memset(pBuffer, 0, MAX_BUFFER_SIZE);
- pParam->pBuffer = pBuffer;
- pParam->dwBufferSize = MAX_BUFFER_SIZE;
- HANDLE hWatchEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if(NULL == hWatchEvent)
- {
- goto __CLEANUP__;
- }
- pParam->ol.hEvent = hWatchEvent;
- CWinThread* pThread = NULL;
- HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if(NULL == hEvent)
- {
- goto __CLEANUP__;
- }
- pParam->hEvent = hEvent;
- MSG msg;
- while(GetMessage(&msg, NULL, 0, 0))
- {
- switch(msg.message)
- {
- case MSG_STARTWATCH:
- {
- HANDLE hFile = (HANDLE)(msg.wParam);
- PFN_NotifyAction pFn_NotifyAction = (PFN_NotifyAction)(msg.lParam);
- if((INVALID_HANDLE_VALUE == hFile) && (NULL == pFn_NotifyAction))
- {
- break;
- }
- if(NULL == pThread)
- {
- pParam->hFile = hFile;
- pParam->pFn_NotifyAction = pFn_NotifyAction;
- pThread = AfxBeginThread(DirectoryWatch, (LPVOID)pParam, 0, CREATE_SUSPENDED, NULL);
- if(NULL == pThread)
- {
- goto __CLEANUP__;
- }
- pThread->m_bAutoDelete = FALSE;
- pThread->ResumeThread();
- }
- SetEvent(hEvent);
- }
- break;
- case MSG_STOPWATCH:
- {
- ResetEvent(hEvent);
- }
- break;
- case MSG_EXITTHREAD:
- {
- SetEvent(hEvent);
- pParam->bExit = FALSE;
- if((NULL != pThread) && (NULL != pThread->m_hThread))
- {
- WaitForSingleObject(pThread->m_hThread, INFINITE);
- delete pThread;
- pThread = NULL;
- }
- goto __CLEANUP__;
- }
- default:
- break;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- __CLEANUP__:
- if(NULL != hWatchEvent)
- {
- CloseHandle(hWatchEvent);
- hWatchEvent = NULL;
- }
- if(NULL != pBuffer)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- if(NULL != pParam)
- {
- delete pParam;
- pParam = NULL;
- }
- TRACE0("ThreadProc Thread Exit ...\n");
- return 0;
- }
- // 测试代码
- #include "stdafx.h"
- #include "DirectoryWatch.h"
- void NotifyAction(DWORD dwAction, LPWSTR szFile, DWORD dwLength)
- {
- switch(dwAction)
- {
- case FILE_ACTION_ADDED:
- wprintf(L"FILE_ACTION_ADDED: \n\t");
- break;
- case FILE_ACTION_REMOVED:
- wprintf(L"FILE_ACTION_REMOVED: \n\t");
- break;
- case FILE_ACTION_MODIFIED:
- wprintf(L"FILE_ACTION_MODIFIED: \n\t");
- break;
- case FILE_ACTION_RENAMED_OLD_NAME:
- wprintf(L"FILE_ACTION_RENAMED_OLD_NAME: \n\t");
- break;
- case FILE_ACTION_RENAMED_NEW_NAME:
- wprintf(L"FILE_ACTION_RENAMED_NEW_NAME: \n\t");
- break;
- default:
- break;
- }
- WCHAR szPath[MAX_PATH] = {0};
- wmemcpy(szPath, szFile, min(dwLength, MAX_PATH));
- wprintf(L"%s\n", szPath);
- }
- int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
- {
- CDirectoryWatch watch;
- wprintf(L"Start Directory Watch ...\n");
- watch.StartDirectoryWatch(_T("F:\\11"), NotifyAction);
- Sleep(30 * 1000);
- watch.StopDirectoryWatch();
- wprintf(L"Stop Directory Watch ...\n");
- Sleep(10 * 1000);
- wprintf(L"Start Directory Watch ...\n");
- watch.StartDirectoryWatch(_T("F:\\11"), NotifyAction);
- Sleep(30 * 1000);
- watch.StopDirectoryWatch();
- wprintf(L"Stop Directory Watch ...\n");
- Sleep(30 * 1000);
- wprintf(L"Process Exit ...\n");
- return 0;
- }
效果如下图所示:
http://blog.csdn.net/visualeleven/article/details/7562014
ReadDirectoryChangesW 监控文件夹 (一个简单的监控示例程序)(文件被修改了,也可以探测到)的更多相关文章
- gulp插件实现压缩一个文件夹下不同目录下的js文件(支持es6)
gulp-uglify:压缩js大小,只支持es5 安装: cnpm: cnpm i gulp-uglify -D yarn: yarn add gulp-uglify -D 使用: 代码实现1:压缩 ...
- META-INF文件夹是干啥的,META-INF文件夹的作用, META-INF文件夹能删吗
今天有人问到 META-INF文件夹是干啥的,META-INF文件夹的作用, META-INF文件夹能删吗,还有项目的META-INF下面一般会有个MANIFEST.MF 文件,都是干啥的. 百度搜了 ...
- selector是在文件夹drawable中进行定义的xml文件。
获取Drawable对象: Resources res = mContext.getResources(); Drawable myImage = res.getDrawable(R.drawable ...
- 导出不带.svn的文件夹或者是不含.class的文件
转载自:http://blog.csdn.net/z278718149/article/details/21537395 如何导出不带.svn的文件夹或者是不含.class的文件 在工作环境中,有的时 ...
- selector是在文件夹drawable中进行定义的xml文件转载 https://www.cnblogs.com/fx2008/p/3157040.html
获取Drawable对象: Resources res = mContext.getResources(); Drawable myImage = res.getDrawable(R.drawable ...
- 一个简单的P2P传输程序
写了一个简单的P2P传输程序,在P2P的圈子中传输文件,不过为了简便,这个程序没有真正的传输文件,只是简单的判断一下文件的位置在哪里.这个程序可以处理当有一个peer闪退的情况,在这种情况下,剩下的p ...
- Android加载SD卡目录,文件夹遍历,图片设置,设置文件对应打开方式等
此案例主要说的是Android使用GridView加载SD卡下所有目录,文件夹多层遍历,文件图标修改,设置文件对应打开方式等功能. 如图: 代码: public class GridViewFile ...
- IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序
前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...
- iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序
iOS开发UI篇—使用嵌套模型完成的一个简单汽车图标展示程序 一.plist文件和项目结构图 说明:这是一个嵌套模型的示例 二.代码示例: YYcarsgroup.h文件代码: // // YYcar ...
随机推荐
- 一款jQuery仿海尔官网全屏焦点图特效代码
一款jQuery仿海尔官网全屏焦点图特效代码,带有左右箭头的jQuery焦点图切换特效. 当焦点图切换时,下方的三块小图也相对应的进行切换.并且特效还兼容头疼的IE6.赶快去和谐了它吧! 适用浏览器: ...
- python 安装 setuptools Compression requires the (missing) zlib module 的解决方案
背景: 虚拟机centos下安装python辅助工具 setuptools报错,错误信息大概如下: Traceback (most recent call last): File "setu ...
- 飞行器的Pitch Yaw Roll概念图解
前进方向为Z轴 Pitch 升降 绕X轴 对应常见Φ(phi)角: Yaw 偏航 绕Y轴 对应常见θ(theta)角: Roll 翻滚 绕Z轴 对应常见φ(psi)角: 对应表: 参考网址NASA: ...
- PyQt4学习笔记1:PyQt4第一个程序
创建一个 PyQt4 一般可以通过很少的步骤完成.通常的方法是用Qt 提供的QtDesigner工具创建界面.使用QtDesigner,可以方便地创建复杂的GUI界面.然后,可以在窗口上创建部件, 添 ...
- Winform上传下载文件代码
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.IO ...
- UserLogin
DAL: IUserDAL namespace Dal { /// <summary> /// This interface is defined for user functions. ...
- 【原创】CHROME 最小字体限制为12PX的终极解决方案
CHROME 最小字体限制为12PX的终极解决方案 本文由五月雨恋提供,转载请注明出处. 相信不少做网站的用户会有这样一个问题,Chrome 默认最小字体是12px(最新版英文也有此问题),这个是 C ...
- cocos2dx中的格子地图TileMap
格子地图的优点: a.节省内存,我们知道对于一款游戏来说,如果以图片来作为地图的话,对于神庙逃亡,魂斗罗这样的场景很多,地图很长的游戏显然不现实,因为图片很占内存,但是这些游戏的地图有一个特点就是:重 ...
- 打造自己的程序员品牌(摘自Infoq)
John Sonmez是Simple Programmer的创始人.作者与程序员,关注于如何让复杂的事情变得简单.他是一位专业的软件开发者.架构师与讲师,感兴趣的领域包括测试驱动开发.如何编写整洁的代 ...
- Careercup - Facebook面试题 - 5179916190482432
2014-05-01 00:45 题目链接 原题: input [,,,] output [,,,] Multiply all fields except it's own position. Res ...