我实现了一个程序,使用ReadDirectoryChangesW
重叠模式和完成例程来跟踪给定文件夹中的更改。效果很好。
我计划重建它,使其成为一个更加通用的图书馆。
当完成例程cr
调用并且文件更改显示时,我需要继续跟踪:参见行DoRDC = true; // RESTART WATCHING
。
在当前版本中这是可能的,因为它在循环中运行while (_kbhit() == 0) {
,但重建后我将消除这个循环。
WatchDirectory
只会在开始时调用ReadDirectoryChangesW
。
我的问题是:我应该如何重新启动内部跟踪?在完成例程内部cr
调用是否正确?但是当上一次调用未完成时,可能会导致调用...也许有一种方法可以告诉不要停止跟踪?ReadDirectoryChangesW
cr
cr
ReadDirectoryChangesW
我的代码如下。主要函数 - WatchDirectory();
LPVOID lpBuffer = NULL;
bool DoRDC = true;
VOID WINAPI cr(DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped) {
// Completion routine
DoRDC = true; // RESTART WATCHING
std::wcout << L" ------------- lpCompletionRoutine --------------- " << std::endl;
std::wcout << L" ErrCode = " << dwErrorCode
<< L" BytesTransferred = " << dwNumberOfBytesTransfered << std::endl;
if (dwErrorCode != 0) {
return;
}
std::wcout << L"..............." << std::endl;
// simply display dir changes
DisplayFileInfo(lpBuffer, dwNumberOfBytesTransfered);
}
bool WatchDirectory(LPTSTR lpDir)
{
// AFTER RECONSTRUCTION WILL CALL ReadDirectoryChangesW 1 TIME WITHOUT A LOOP
DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];
TCHAR lpDrive[4];
TCHAR lpFile[_MAX_FNAME];
TCHAR lpExt[_MAX_EXT];
HANDLE hDir = INVALID_HANDLE_VALUE;
std::wcout << L"3_Watching for: " << lpDir << std::endl;
_tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
lpDrive[2] = (TCHAR)'\\';
lpDrive[3] = (TCHAR)'\0';
int EventsNumber = 1;
DWORD Flags = FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_FILE_NAME;
hDir = CreateFile(lpDir, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
if (hDir == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
std::wcout << L"ERROR: CreateFile(folder to trace) function failed = " << err << std::endl;
return false;
///ExitProcess(err);
}
DWORD nBufferLength = 30000;
lpBuffer = malloc(nBufferLength);
BOOL bWatchSubtree = TRUE;
DWORD BytesReturned = 0;
HANDLE hEvent = CreateEvent(NULL, FALSE /*manual reset = true*/, FALSE /* initial state*/, NULL);
if (hEvent == NULL) {
printf("\n Cannot create event.\n");
CloseHandle(hDir);
return false;
//ExitProcess(GetLastError());
}
// =============================================================
OVERLAPPED Overlapped;
//---Overlapped.hEvent = hEvent;
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine = cr;
// =============================================================
DoRDC = true;
while (_kbhit() == 0) {
if (DoRDC) {
ZeroMemory(&Overlapped, sizeof(Overlapped));
BOOL res_rdc = ReadDirectoryChangesW(hDir,
lpBuffer,
nBufferLength,
bWatchSubtree,
Flags,
&BytesReturned,
&Overlapped,
lpCompletionRoutine);
bool ok_rdc = (res_rdc != 0);
if (ok_rdc) {
}
else {
DWORD err = GetLastError();
std::wcout << L"ReadDirectoryChangesW error = " << err << std::endl;
}
DoRDC = false;
}
// Wait for notification.
//std::wcout << L"SleepEx" << std::endl;
SleepEx(1000, TRUE);
}
CloseHandle(hEvent);
CloseHandle(hDir);
free(lpBuffer);
}