C#中如何判断一个目录是回收站?
给定一个文件夹,我如何判断它是回收站?我找到了答案 适用于 C++,但不适用于 C#。
我的第一个想法是检查 FileAttributes.System (在我的情况下这是一个可接受的近似值),但实际上该标志已在回收文件夹中清除。
使用硬编码文件夹名称的粗略解决方案是不可能的(毕竟我们已经是 2009 年了)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这里有一个小问题。 Windows 回收站是一个虚拟文件夹,实际上并不存在。您看到的文件实际上并不位于该文件夹中,它们是磁盘上现有文件的表示,这些文件已重命名为特殊名称,这会将它们从可见文件系统中“删除”,但不会从物理文件系统中删除。
您可以通过使用 win32 API 询问文件夹位置来自己“证明”这一点。它将返回回收站的
E_FAIL
,但不会返回其他文件夹(请参阅 pinvoke.net 上的 SHGetKnownFolderPath (并在 MSDN 上)了解您可以使用的所有常量以及运行此代码所需的声明):每个驱动器都会重复伪造的文件夹名称 “$Recycle.bin”。隐藏名称不存储在注册表中,因此 API 无法访问它。之前建议的 KnownFolderHelper 也不会检索此信息(同一个库有一个用于获取回收站的命名方法,它还有一个 GetPath,它将显示为空)。
但一切并没有失去。这个虚假的不存在的“文件名”或“文件夹名”包含一个类似于“S-1-5-21-2703390745-3900912742-210389625-1000”的隐藏文件(您的将是不同的)。这是查明某个文件名是否实际上是回收站虚拟目录的两种“可靠”方法之一(另一种方法是:通过
SHFileOperation
, 在这里解释,并检查它是否出现在你拥有的文件夹中):注意:我不知道其他 win32 版本上的隐藏文件夹是什么,你'我必须尝试一下。它们都设置了系统和隐藏标志,看起来像一个损坏的 GUID。
API 文档对此不是很清楚,但如果您需要确认,此页面解释确实没有可以检索的路径(较旧的 CSIDL 相关页面对此不太清楚)。
更新:使用
SHGetSpecialFolderPath
,SHGetSpecialFolderLocation
、ShellAPI.SHGetFolderLocation
和SHGetPathFromIDList
都因相同的原因而失败:要么是空结果,要么是错误。我测试了回收站和 AppData 的所有功能(以确保我使用了正确的参数)。仅有关
ShGetPathFromIDListEx
明确表示,引用:“除了 UNC 打印机名称之外,如果 pidl 参数指定的位置不是文件系统的一部分,则此函数失败。”。There's a little problem here. The Windows Recycle Bin is a virtual folder and does not actually exist. The files that you see are not actually in that folder, they are the representation of existing files on disk that have been renamed to a special name, which "removes" them from the visible file system, but not the physical one.
You can "proof" this for yourself by asking for the folder location using the win32 API. It will return
E_FAIL
for the Recycle Bin, but not for other folders (see SHGetKnownFolderPath on pinvoke.net (and on MSDN) for all constants you can use and the declarations needed for this code to run):The fake foldername "$Recycle.bin" is repeated for each drive. The hidden name is not stored in the registry and it is not accessible by the API as such. The earlier suggested KnownFolderHelper will not retrieve this information either (the same lib has a named method for getting the Recycle Bin, it also has a
GetPath
, it will turn up empty).But all is not lost. This fake non-existing "file name" or "folder name" contains a hidden file that looks something like "S-1-5-21-2703390745-3900912742-210389625-1000" (yours will be different). It's one of two "reliable" ways to find out whether a certain filename is actually a virtual directory of the recycle bin (the other way being: delete a file through
SHFileOperation
, explained here, and check whether it appears in the folder you have):Note: I don't know what the hidden folders are on other win32 versions, you'l have to experiment a bit. They all have the system and hidden flag set and look like a mangled GUID.
The API docs are not very clear about it, but if you need confirmation, this page explains that there really is no path that can be retrieved (the older CSIDL related page is much less clear on it).
Update: alternative approaches with
SHGetSpecialFolderPath
,SHGetSpecialFolderLocation
,ShellAPI.SHGetFolderLocation
andSHGetPathFromIDList
all fail with the same: either an empty result or an error. I tested all functions both for Recycle Bin and for AppData (to be sure I used the correct parameters).Only the documentation on
ShGetPathFromIDListEx
said it explicitly, quote: "Except for UNC printer names, if the location specified by the pidl parameter is not part of the file system, this function fails.".Microsoft 的 Windows API 代码包 包含此功能。
要获取回收站的文件夹,请使用
我不知道该字符串的含义,但它作为对回收站的引用包含在文档中。
希望这有帮助:)
Microsoft's Windows API Code Pack contains this functionality.
To get the folder of the Recycle Bin, use
I've no idea what that string means, but it was included in the docs as the reference to the Recycle Bin.
Hope this helps :)
正如您提到的,大多数与回收站相关的方法都是用 C++ 编写的。您可以使用 托管扩展在应用程序中创建包装类到 C++,那么您必须像这样使用 DLLImport:
还有一些文章以其他方式使用 C# 执行此操作,其中大多数使用 PInvoke 或依赖于名称中包含 $Recycle 的文件夹。以下是我找到的有关此主题的一些链接
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/05f1476f-a101-4766-847b-0bdf4f6ad397
http://www.codeproject.com/KB/shell/recyclebin.aspx
http://www.pinvoke.net/default.aspx/shell32.SHFileOperation
Most of the recycle bin related methods have been written in C++ as you mentioned. You could create a wrapper class in your application using the managed extensions to C++, then you will have to use DLLImport like this:
There are also articles out there that do this some other way with C#, most of them use PInvoke or rely on the folder having $Recycle in it's name. Following are a few links I've found for this subject
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/05f1476f-a101-4766-847b-0bdf4f6ad397
http://www.codeproject.com/KB/shell/recyclebin.aspx
http://www.pinvoke.net/default.aspx/shell32.SHFileOperation