这个问题并不像我最初想象的那样简单。然而,我发现它仍然是可以解决的。
首先,您需要知道回收站的使用情况。Win32 的 SHQueryRecycleBin 可以为您完成此操作:
[DllImport("shell32.dll")]
static extern int SHQueryRecycleBin(string pszRootPath, ref SHQUERYRBINFO pSHQueryRBInfo);
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct SHQUERYRBINFO
{
public int cbSize;
public long i64Size;
public long i64NumItems;
}
使用以下演示代码来检索此信息:
const int S_OK = 0;
//string drivePath = @"C:\$RECYCLE.BIN\";
string drivePath = @"D:\$RECYCLE.BIN\";
SHQUERYRBINFO pSHQueryRBInfo = new SHQUERYRBINFO();
pSHQueryRBInfo.cbSize = Marshal.SizeOf(typeof(SHQUERYRBINFO));
int hresult = SHQueryRecycleBin(drivePath, ref pSHQueryRBInfo);
Console.WriteLine("{0} Drive {1} contains {2} item(s) in {3:#,##0} bytes",
hresult == S_OK ? "Success!" : "Fail!",
drivePath, pSHQueryRBInfo.i64NumItems, pSHQueryRBInfo.i64Size);
其次,在Windows 7上(至少在Windows 7上),用户可以确定他们在(几乎)每个驱动器上为回收站保留多少空间。因此,您需要知道我们可以获取的每个驱动器的回收站的最大容量。这些信息可以在注册表中找到。但是,我们还需要检索所有驱动器的GUID:
/// <summary>
/// Get from the registry all the drive guids
/// </summary>
static string[] GetDriveIds()
{
const string registryPath = @"Software\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume\";
RegistryKey reg = Registry.CurrentUser.OpenSubKey(registryPath);
string[] readIn = reg.GetSubKeyNames();
string[] driveIds = new string[readIn.Length - 1];
Array.Copy(readIn, 1, driveIds, 0, readIn.Length - 1); // The first item must be removed
return driveIds;
}
/// <summary>
/// Get and return the drive's recycle bin's MaxCapacity
/// </summary>
/// <param name="driveId">The guid of the specified drive</param>
/// <returns>The size in mega bytes</returns>
static int FindDriveCapacity(string driveId)
{
const string registryPath = @"Software\Microsoft\Windows\CurrentVersion\Explorer\BitBucket\Volume\{0}\";
RegistryKey reg = Registry.CurrentUser.OpenSubKey(
string.Format(registryPath, driveId));
return (int)reg.GetValue("MaxCapacity", 0);
}
使用以下代码,您可以检索每个驱动器的最大容量:
string[] driveIds = GetDriveIds();
int driveNo = 0;
foreach (string driveId in driveIds)
{
Console.WriteLine("{0}. MaxCapacity of drive {1} is {2:#,##0} bytes",
++driveNo, driveId, FindDriveCapacity(driveId));
}
我们需要做的最后一件事情是将GUID与驱动器字母进行映射。我们仍需使用注册表:
```html
最后一步需要使用注册表来将GUID映射到驱动器字母。
```
static string MapDriveLetter(string driveId)
{
const string registryPath = @"SYSTEM\MountedDevices";
RegistryKey reg = Registry.LocalMachine.OpenSubKey(registryPath);
string[] readIn = reg.GetValueNames();
byte[] keyCode = {};
Regex regGuid = new Regex(@"\{[^\}]+\}");
Regex regDriveLetter = new Regex(@"[A-Z]:$");
foreach (string keyRead in readIn) {
if (regGuid.IsMatch(keyRead) && regGuid.Match(keyRead).Value == driveId )
keyCode = (byte[])reg.GetValue(keyRead, null);
}
foreach (string keyRead in readIn)
{
byte[] codeRead = (byte[])reg.GetValue(keyRead, null);
if (!regGuid.IsMatch(keyRead) && keyCode.SequenceEqual(codeRead))
{
if (regDriveLetter.IsMatch(keyRead))
return regDriveLetter.Match(keyRead).Value;
}
}
return string.Empty;
}
只需传递 GUID,您就可以获得驱动器号:
string code = MapDriveLetter("{f4b90148-66f6-11e3-9ac5-806e6f6e6963}");
综合所有信息,你应该能够确定系统会永久删除哪个驱动器上多大的文件或文件。