【发布时间】:2018-04-19 23:39:02
【问题描述】:
我正在使用FindFirstFile 和FindNextFile 在我的应用程序中显示给定文件夹中的文件列表。
有时,我看到我的应用程序使用SHFileOperation 删除了一个文件夹,但FindFirstFile 仍然可以找到该文件夹。我曾在 StackOverflow 上看到过此问题:File deleted with remove function still shows up in FindFirstFile/FindNextFile。但是,在我的情况下,我没有使用remove,即使在清除回收站后该文件夹仍然可见。此外,该文件夹在 Windows 文件资源管理器中不可见。这让我想知道文件资源管理器正在过滤什么以忽略文件。
我尝试查看文件属性,但只发现删除的文件夹设置了FILE_ATTRIBUTE_DIRECTORY 和FILE_ATTRIBUTE_VIRTUAL。 FILE_ATTRIBUTE_VIRTUAL 属性有点神秘(MSDN 说它是为系统使用而保留的),所以我尝试忽略具有该属性集的文件夹。但是,事实证明存在具有此属性集的合法现有/活动文件夹,因此我无法将其用作过滤器。
为什么会出现这个文件夹?如何忽略它而不忽略现有(未删除)文件夹?
【问题讨论】:
-
删除目录是一件非常危险的事情,它经常被另一个应用程序锁定。标准情况是它是另一个进程的默认工作目录,由 FileSystemWatcher、搜索索引器或反恶意软件程序在目录中的文件中进行观察。所有这些都需要做 something 以避免难以删除目录。他们通过删除共享打开文件和目录句柄。这允许进程删除目录。但是文件和目录在最后一个句柄关闭之前不会消失。
-
@HansPassant 删除文件夹时当然有一些注意事项。但我要重申:如果文件夹上还有一个句柄打开,因此还不能真正删除,为什么
SHFileObject删除操作成功,为什么文件夹没有出现在Windows文件中探险家?显然,该程序正在以某种方式过滤掉这个文件夹,这在查看FindFirstFile属性文档时并不明显。 -
没有什么特别的魔法。 SHFileObject() 的好处是它是一个 shell 函数,因此可以让 Explorer 知道它应该隐藏目录。查看 SHChangeNotify() 的文档以了解其背后的管道。
-
FILE_ATTRIBUTE_VIRTUAL表示它是一个虚拟存在的文件/目录,用于 32 位应用程序,它没有以requestedExecutionLevel显示,因此不是 UAC aware。真实文件/目录位于用户的虚拟文件存储“%LocalAppdata%\VirtualStore”中。您可以在任务管理器或进程资源管理器中检查您的应用程序是否启用了 UAC 虚拟化。 -
如果您的应用程序是虚拟化的,它会看到受保护系统目录中的文件,而这些文件实际上位于用户的
"%LocalAppData%\VirtualStore"中。 Explorer 不会看到这些虚拟文件,因为它是一个支持 UAC 的 64 位应用程序,因此未虚拟化。