标签:判断 box 删除文件 ati 权限 false this new 句柄
实现文件监控操作的核心函数是ReadDirecotryChangesW。这个API函数可以设置监控目录、过滤条件,从而获取监控数据。在调用API函数ReadDirecotryChangesW设置监控过滤条件之前,需要先通过CreateFile函数打开监控目录,获取监控目录的句柄。之后才能调用ReadDirecotryChangesW函数设置监控过滤条件并阻塞,直到有满足监控过滤条件的操作,ReadDirecotryChangesW才会返回监控数据继续往下执行。接下来便根据返回的监控数据,判断操作类型以及获取相关数据。
注意:调用一次ReadDirectoryChangesW函数,只会监控一次。要想实现持续监控,则需要程序循环调用ReadDirectoryChangesW函数来设置监控并获取监控数据。由于持续的目录监控需要不停循环调用ReadDirecotryChangesW函数进行设置监控和获取监控数据,所以,如果把这段代码放在主线程中,则可能会导致程序阻塞。为了解决主线程阻塞的问题,可以创建一个文件监控子线程,把文件监控的实现代码放到子线程中运行
(1).打开目录,获取文件句柄(必须要用FILE_LIST_DIRECTORY 权限与FILE_FLAG_BACKUP_SEMANTICS标志)
(2).设置目录监控
(3).判断文件操作类型
//开启监控按钮 void CFileMonitDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); //检测文件是否存在 if (GetFileAttributes(m_Edit_Path) == INVALID_FILE_ATTRIBUTES) { MessageBox(_T("文件不存在 请重试!")); return; } USES_CONVERSION; //创建线程 CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorFileThreadProc, this, 0, NULL); return; } // 目录监控多线程 UINT MonitorFileThreadProc(LPVOID lpVoid) { CFileMonitDlg* ptrData = (CFileMonitDlg*)lpVoid; CString temp; temp = ptrData->m_Edit_Path + L"\\"; // 打开目录, 获取文件句柄 HANDLE hDirectory = ::CreateFile(temp.GetBuffer(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (INVALID_HANDLE_VALUE == hDirectory) { MessageBoxA(0, "CreateFileA Error", "Error", MB_OK); return 1; } DWORD dwBufferSize = 4096; // 申请一个足够大的缓冲区 BYTE* pBuf = new BYTE[dwBufferSize]; if (NULL == pBuf) { MessageBoxA(0, "new Error", "Error", MB_OK); return 2; } FILE_NOTIFY_INFORMATION* pFileNotifyInfo = (FILE_NOTIFY_INFORMATION *)pBuf; BOOL bRet = FALSE; DWORD dwRet = 0; CString res = L""; // 开始循环设置监控 do { ::RtlZeroMemory(pFileNotifyInfo, dwBufferSize); // 设置监控目录 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) { MessageBoxA(0, "ReadDirectoryChangesW Error", "Error", MB_OK); break; } // 判断操作类型并显示 switch (pFileNotifyInfo->Action) { //新增文件 case FILE_ACTION_ADDED: { temp.Format(_T("%s:%s\r\n"), _T("新增文件"), pFileNotifyInfo->FileName); res += temp + L"\r\n"; break; } //删除文件 case FILE_ACTION_REMOVED: { temp.Format(_T("%s:%s\r\n"), _T("删除文件"), pFileNotifyInfo->FileName); res += temp + L"\r\n"; break; } //修改文件 case FILE_ACTION_MODIFIED: { temp.Format(_T("%s:%s\r\n"), _T("修改文件"), pFileNotifyInfo->FileName); res += temp + L"\r\n"; break; } //重命名文件 case FILE_ACTION_RENAMED_OLD_NAME: { temp.Format(_T("%s:%s\r\n"), _T("重命名前文件"), pFileNotifyInfo->FileName); res += temp + L"\r\n"; break; } case FILE_ACTION_RENAMED_NEW_NAME: { temp.Format(_T("%s:%s\r\n"), _T("重命名后文件"), pFileNotifyInfo->FileName); res += temp + L"\r\n"; break; } default: break; } SetDlgItemText(ptrData->m_hWnd,IDC_EDIT2, res); } while (bRet); // 关闭句柄, 释放内存 CloseHandle(hDirectory); delete[] pBuf; return 0; }
标签:判断 box 删除文件 ati 权限 false this new 句柄
原文地址:https://www.cnblogs.com/ndyxb/p/12913790.html