-->

我如何才能知道一个目录是C#回收站吗?(How can I tell that a director

2019-08-20 01:04发布

给定一个文件夹,我怎么能告诉,这是一个回收站? 我找到了一个答案为C ++而不是C#。

我的第一个想法是,以检查FileAttributes.System(这将是我的情况下可接受的近似值),但实际上该标志,在回收文件夹清空。

使用硬编码的文件夹名称原油的解决方案是出了问题(我们是在2009年之后全部)。

Answer 1:

这里有一个小问题。 Windows回收站是一个虚拟文件夹,实际上并不存在。 您看到的文件实际上不是该文件夹中,它们是现有的文件在磁盘上表示已重命名为一个特殊的名字,从可见的文件系统“删除”出来的,而不是物理的。

你可以在“证明”自己这一点通过要求使用Win32 API的文件夹位置。 它会返回E_FAIL回收站,但不支持其他的文件夹(参见上pinvoke.net SHGetKnownFolderPath ( 和MSDN )为您可以使用所有的常量,需要对这个代码运行的声明):

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
}

假文件夹名“$ RECYCLE.BIN”重复每个驱动器。 隐藏的名称不存储在注册表中,它是不是由API本身进行访问。 早期的建议KnownFolderHelper不会检索这些信息是(同LIB有越来越回收站中命名的方法,它也有一个GetPath ,它会变成了空的)。

但没有失去一切。 这种假不存在“文件名”或“文件夹名称”含有一个隐藏的文件,看起来像“S-1-5-21-2703390745-3900912742-210389625-1000”(你的将是不同的)。 这两个“可靠”的方法找出某个文件名是否实际上是回收站的虚拟目录之一(另一种方式存在:删除通过文件SHFileOperation , 这里解释 ,并检查它是否出现你的文件夹中) :

string [] entries = Directory.GetFileSystemEntries(@"c:\$Recycle.bin", "?-?-?-??*");
if(entries.Length > 0)
   // we have a winner
else 
   // no, not the recycle bin

注:我不知道隐藏的文件夹是其他Win32版本是什么,you'l要实验一下。 它们都具有系统和隐藏标志设置,看起来像一个错位的GUID。

API文档是不是很清楚,但如果你需要确认, 此页解释了 ,真的有没有可以检索(路径年长CSIDL相关页面上它更不太清楚)。

更新:有替代办法SHGetSpecialFolderPathSHGetSpecialFolderLocationShellAPI.SHGetFolderLocationSHGetPathFromIDList全部失败以相同的:无论是一个空的结果或错误。 我测试了回收站和应用程序数据的所有功能(以确保我用正确的参数)。

只有在文档ShGetPathFromIDListEx说,这明确,报价:“除了UNC打印机名称,如果由PIDL参数指定的位置不是文件系统的一部分,此函数失败。”



Answer 2:

微软的Windows API代码包包含此功能。

为了得到回收站的文件夹,使用

Microsoft.WindowsAPICodePack.Shell.KnownFolderHelper.FromPath("::{645FF040-5081-101B-9F08-00AA002F954E}");

我不知道是什么意思的字符串,但它被包含在文档作为参考回收站。

希望这可以帮助 :)



Answer 3:

大多数回收站相关的方法已经写在C ++中,你提到的。 你可以使用你的应用程序创建一个包装类托管扩展到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或依赖于它的名字有文件夹$回收站。 以下是我已经找到了这个问题的几个环节

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



文章来源: How can I tell that a directory is the recycle bin in C#?