FindFirstChangeNotification 锁定父文件夹

Posted

技术标签:

【中文标题】FindFirstChangeNotification 锁定父文件夹【英文标题】:FindFirstChangeNotification locks parent folder 【发布时间】:2015-01-15 11:22:18 【问题描述】:

我正在使用 FindFirstChangeNotification()/ReadDirectoryChangesW() 来监视文件夹的更改。它按预期工作。我的问题是:当我尝试重命名 Watched 文件夹的父级时,访问被拒绝,错误 5。我猜我的 FCN 句柄已打开文件夹以进行通知监视,并且不允许更改父级。

有什么方法可以监控子目录,比如 c:\folder\subfolder\anotherfolder\ 并且仍然能够打开命令提示符(或其他程序)并执行“重命名 c:\folder\ c:\folder2 "

这是我的代码 sn-p

    //
    // Sign up for notifications on the object. 
    //
    m_bWatchSubTree = TRUE;
    m_dwWatchFlags =
        FILE_NOTIFY_CHANGE_SECURITY |       // (0x100) change to security descriptor (NTFSACL?)
        FILE_NOTIFY_CHANGE_CREATION |       // (0x40) change to creation date
        FILE_NOTIFY_CHANGE_LAST_ACCESS |    // (0x20) change to last access date  
        FILE_NOTIFY_CHANGE_LAST_WRITE |     // (0x10) any change to the modification date/time of file in the folder
        FILE_NOTIFY_CHANGE_SIZE |           // (0x08) Size changed
        FILE_NOTIFY_CHANGE_ATTRIBUTES |     // (0x04) Atributes of something changed
        FILE_NOTIFY_CHANGE_DIR_NAME |       // (0x02) DIR name change in watched folder rename,create,delete FOLDER
        FILE_NOTIFY_CHANGE_FILE_NAME;       // (0x01) FILE name change in watched folder. rename,create,delete FILE

    CString strObjectPathAndName(_T("c:\\folder\\subfolder\\anotherfolder\\");
    m_hChangeHandle = ::FindFirstChangeNotification(strObjectPathAndName, m_bWatchSubTree, m_dwWatchFlags);
    if (m_hChangeHandle != INVALID_HANDLE_VALUE)
    
        DWORD dwStatus = ::WaitForSingleObject(m_hChangeHandle, INFINITE);
        HANDLE  hDir = ::CreateFile(strObjectPathAndName, 
                                FILE_LIST_DIRECTORY,
                                FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE,
                                NULL, //security attributes
                                OPEN_EXISTING,
                                FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,          
                                NULL);
        DWORD dwBytesReturned = 0;
        FILE_NOTIFY_INFORMATION *p = (FILE_NOTIFY_INFORMATION*)nb.GetBuffer();
        if (::ReadDirectoryChangesW(hDir, p, nb.GetMaxSize(), m_bWatchSubTree, m_dwWatchFlags, &dwBytesReturned, NULL, NULL))
        
        //
        // do some stuff
        
    

【问题讨论】:

【参考方案1】:

不确定这是否是您需要的,

如果您有兴趣在 c:\folder\subfolder\anotherfolder\ 中保留当前侦听器的同时侦听 ANOTHER 路径,您将需要一个 HANDLE 类型的数组。

在您的代码中,它将如下所示:

HANDLE m_hChangeHandle[x];// int x should be the quantity of your desired listeners.

当然,您需要为每个数组使用FindFirstChangeNotification,即:

m_hChangeHandle[0] = FindFirstChangeNotification(..., ..., ...);
m_hChangeHandle[1] = FindFirstChangeNotification(..., ..., ...);
//and so on..

由于您现在使用的侦听器超过 1 个,因此您不能继续使用 WaitForSingleObject 而是使用 WaitForMultipleObjects。即:

WaitForMultipleObjects(x, m_hChangeHandle, FALSE, INFINITE);//False will wait for a change in at least one of the listeners.

希望这是你需要的。

【讨论】:

您好,感谢您的输入,但不,我不想监视其他文件夹。当子文件夹是更改通知观察程序的目标时,我特别需要重命名子文件夹的父文件夹。我的解决方法是始终在顶层监听并忽略任何超出我需要的范围的更改通知。 但是为什么不只听您需要的实际子文件夹,正如您所说,如果发生更改,请重命名其父文件夹。除非我没有正确理解用例

以上是关于FindFirstChangeNotification 锁定父文件夹的主要内容,如果未能解决你的问题,请参考以下文章