给定一个文件夹,我怎么知道它是一个回收站?我找到了answer用于C ++而不用于C#。
我的第一个想法是检查FileAttributes.System(在我的情况下这是一个可接受的近似值),但实际上该标志在回收文件夹中被清除。
使用硬编码文件夹名称的原始解决方案是不可能的(毕竟我们在2009年)。
答案 0 :(得分:7)
这里有一点问题。 Windows回收站是一个虚拟文件夹,实际上并不存在。您看到的文件实际上不在该文件夹中,它们是磁盘上已重命名为特殊名称的现有文件的表示形式,它将它们从可见文件系统中“删除”,而不是从物理系统中删除。
您可以通过使用win32 API询问文件夹位置来自行“证明”此操作。它将为回收站返回E_FAIL
,但不会为其他文件夹返回(请参阅SHGetKnownFolderPath on pinvoke.net(and on MSDN)以获取可以使用的所有常量以及运行此代码所需的声明):< / p>
IntPtr ptrRecycleBinPath;
// try it with KnownFolder.QuickLaunch to see it working:
HRESULT hr = (HRESULT) SHGetKnownFolderPath(
KnownFolder.RecycleBinFolder,
0,
IntPtr.Zero,
out ptrRecycleBinPath);
if (hr == HRESULT.E_FAIL)
{
Console.WriteLine("No folder avaialable, virtual folder");
}
else if (hr == HRESULT.S_OK)
{
string RecycleBinPath = Marshal.PtrToStringUni(ptrRecycleBinPath);
Marshal.FreeCoTaskMem(ptrRecycleBinPath);
Console.WriteLine("path: " + RecycleBinPath);
}
// for convenience, you can use the code above
// directly if you paste the follow declarations in your class:
// get a "known path"
[DllImport("shell32.dll")]
static extern long SHGetKnownFolderPath(
[MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
uint dwFlags,
IntPtr hToken,
out IntPtr pszPath);
// known folder GUID declarations
public static class KnownFolder
{
// many more entries exist, left out for clarity here
public static readonly Guid RecycleBinFolder =
new Guid("B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC");
public static readonly Guid QuickLaunch =
new Guid("52a4f021-7b75-48a9-9f6b-4b87a210bc8f");
//....
}
// results of COM invocations:
enum HRESULT : uint
{
S_FALSE = 0x0001,
S_OK = 0x0000,
E_FAIL = 0x80004005,
E_INVALIDARG = 0x80070057,
E_OUTOFMEMORY = 0x8007000E
}
对每个驱动器重复伪造的foldername “$ Recycle.bin”。隐藏名称不存储在注册表中,API无法访问它。之前建议的KnownFolderHelper也不会检索此信息(同一个lib有一个命名方法来获取回收站,它也有一个GetPath
,它会变空。)
但并非一切都没有丢失。这个假的不存在的“文件名”或“文件夹名称”包含一个隐藏文件,看起来像“S-1-5-21-2703390745-3900912742-210389625-1000”(你的将是不同)。这是找出某个文件名是否实际上是回收站的虚拟目录的两种“可靠”方法之一(另一种方式是:通过SHFileOperation
,explained here删除文件,并检查它是否是出现在您拥有的文件夹中):
string [] entries = Directory.GetFileSystemEntries(@"c:\$Recycle.bin", "?-?-?-??*");
if(entries.Length > 0)
// we have a winner
else
// no, not the recycle bin
注意:我不知道其他win32版本上的隐藏文件夹是什么,你需要进行一些实验。它们都设置了系统和隐藏标志,看起来像一个错位的GUID。
API文档不是很清楚,但是如果你需要确认,this page explains确实没有可以检索的路径(older CSIDL related page就不太清楚了。)< / p>
更新: SHGetSpecialFolderPath
,SHGetSpecialFolderLocation
,ShellAPI.SHGetFolderLocation
和SHGetPathFromIDList
的替代方法都失败了:无论是空结果还是错误。我测试了回收站和AppData的所有功能(确保我使用了正确的参数)。
只有ShGetPathFromIDListEx
上的文档明确说明,引用:“除了UNC打印机名称,如果pidl参数指定的位置不是文件系统的一部分,则此函数失败。”< / em>的
答案 1 :(得分:3)
Microsoft的Windows API Code Pack包含此功能。
要获取回收站的文件夹,请使用
Microsoft.WindowsAPICodePack.Shell.KnownFolderHelper.FromPath("::{645FF040-5081-101B-9F08-00AA002F954E}");
我不知道该字符串的含义,但它作为对回收站的引用包含在文档中。
希望这会有所帮助:)
答案 2 :(得分:2)
如您所述,大多数与回收站相关的方法都是用C ++编写的。你可以使用managed extensions to C++在你的应用程序中创建一个包装类,然后你必须像这样使用DLLImport:
using System;
using System.Runtime.InteropServices;
class MainApp
{
[DllImport("user32.dll", EntryPoint="MessageBox")]
public static extern int MessageBox(int hWnd, String strMessage, String
strCaption, uint uiType);
public static void Main()
{
MessageBox( 0, "Hello, this is PInvoke in operation!", ".NET", 0 );
}
}
还有一些文章用C#做其他方式,其中大多数使用PInvoke或依赖于其名称中包含$ Recycle的文件夹。以下是我为此主题找到的一些链接
http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/05f1476f-a101-4766-847b-0bdf4f6ad397