好久没写博客了,1.懒 2.不会总结...
因工作需要文件监控,遂接触ReadDirectoryChangesW函数。第一次写的时候用的同步处理。导致线程不会退出。后来改成异步处理也不是很完善。
看了 http://blog.youkuaiyun.com/visualeleven/article/details/7562014 的代码,受到很大启发。不过由于他的类只能针对一个目录使用。我便对其完善了一下。
名称:CDirectoryWatch
IDE:VS2013
功能:
1. 可开启多个文件监控。
2. 提供监控通知处理接口,使每个监控有单独的 处理函数
其他:
1. 使用异步ReadDirectoryChangesW
2. 使用消息处理
3. 还凑活的 调试反馈
BUG:连续开启同一个文件的监控是检测不到 已经开启相同监控
原因:开启函数里面的扫描列表和 消息处理里面的添加列表不同步
咳咳,英语太渣..混合注释
欢迎 各位童鞋 指出错误~
// DirectoryWatch.h
#pragma once
#include <windows.h>
#include <list>
// 通用的通知处理函数
typedef void(*funNotifyAction)(DWORD dwAction, LPWSTR wzSrcFile, LPWSTR wzDestFile);
// 要监控的目录的信息
typedef struct _WATCH_PARAM
{
_WATCH_PARAM()
{
hFile = INVALID_HANDLE_VALUE;
hEvent = NULL;
hWatch = NULL;
pBuffer = NULL;
bIsExit = FALSE;
dwBufferSize = 0;
NotifyAction = NULL;
ZeroMemory(&wzPath, sizeof(WCHAR)*MAX_PATH);
ZeroMemory(&ol, sizeof(OVERLAPPED));
}
WCHAR wzPath[MAX_PATH]; // 路径
HANDLE hFile; // 文件句柄
HANDLE hEvent; // 事件句柄
BYTE *pBuffer; // 缓存区
DWORD dwBufferSize; // 缓存区大小
OVERLAPPED ol; // 异步结构
HANDLE hWatch; // 监控线程句柄
BOOL bIsExit; // 监控线程是否退出
funNotifyAction NotifyAction;
}WATCH_PARAM, *PWATCH_PARAM;
// 监控类
class CDirectoryWatch
{
public:
CDirectoryWatch();
virtual ~CDirectoryWatch();
public:
BOOL StartWatch(LPWSTR wzPath, funNotifyAction lpfunNotifyAction);
BOOL StopWatch(LPWSTR wzPath);
private:
static unsigned __stdcall MSGThred(LPVOID lpParam); // 消息线程
static unsigned __stdcall WatchThred(LPVOID lpParam); // 监控线程
void Lock();
void UnLock();
private:
std::list<WATCH_PARAM*> m_vWatchList; // 监控的列表
HANDLE m_hMSG; // 消息线程句柄
DWORD m_dwMSGTID; // 消息线程ID
HANDLE m_hMutex; // 互斥锁(list保护)
};
// DectoryWatch.cpp
#include "stdafx.h"
#include "DirectoryWatch.h"
#include <process.h>
#include <strsafe.h>
#include <Shlwapi.h>
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Shlwapi.lib")
#define MAX_BUFFER_SIZE (1024)
typedef enum _MyMSG
{
MSG_SUCCESS = (WM_USER)+0x100,
MSG_STARTWATCH,
MSG_STOPWATCH,
MSG_EXIT
};
CDirectoryWatch::CDirectoryWatch()
: m_dwMSGTID(0)
, m_hMSG(NULL)
{
m_hMutex = CreateMutexW(NULL, FALSE, NULL