可能重复:
如何使用C#从回收站恢复文件
恢复windows 上删除的文件
我正在开发一个应用程序,该应用程序旨在从系统中恢复已删除的文件(包括回收站中的文件和已从回收站中清空但仍可理解的文件)和格式化的驱动器。我决定把c#作为语言,但我很难找到处理这个问题的类。有人知道任何查找已删除文件、检索文件的类/方法,或者任何教程或帮助吗。我在这方面没有什么经验,所以如果有任何帮助,我们将不胜感激。
没有内置类可以执行您的要求。
事实上,取消删除文件是一个艰难的过程,它需要对文件系统有很低的了解。因此,首先要做的是获取有关包含要撤消删除的文件的驱动器的信息。基本上,你首先想知道它的文件系统。
您将不得不大量使用p/Invoke。首先获取目标驱动器的句柄:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool GetVolumeInformationByHandleW(
IntPtr hDisk,
StringBuilder volumeNameBuffer,
int volumeNameSize,
ref uint volumeSerialNumber,
ref uint maximumComponentLength,
ref uint fileSystemFlags,
StringBuilder fileSystemNameBuffer,
int nFileSystemNameSize);
// Gets a handle to the drive
// Note: use CloseHandle to close the handle you opened once work is done
IntPtr hDrive = NativeMethods.CreateFile(
string.Format("\\.\{0}:", DriveLetter)
GenericRead,
Read | Write,
IntPtr.Zero,
OpenExisting,
0,
IntPtr.Zero);
// Then gets some information about the drive
// The following function requires Vista+
// Use GetVolumeInformation for older systems
const int VolumeNameSize = 255;
const int FileSystemNameBufferSize = 255;
StringBuilder volumeNameBuffer = new StringBuilder(VolumeNameSize);
uint volumeSerialNumber = 0;
uint maximumComponentLength = 0;
uint fileSystemFeatures;
StringBuilder fileSystemNameBuffer = new StringBuilder(FileSystemNameBufferSize);
GetVolumeInformationByHandleW(
hDrive,
volumeNameBuffer,
VolumeNameSize,
ref volumeSerialNumber,
ref maximumComponentLength,
ref fileSystemFeatures,
fileSystemNameBuffer,
FileSystemNameBufferSize);
// Now you know the file system of your drive
// NTFS or FAT16 or UDF for instance
string FileSystemName = fileSystemNameBuffer.ToString();
一旦你有了文件系统的名称,你就必须手动从驱动器中读取原始数据您将读取的内容完全取决于驱动器的文件系统。无论如何,你必须获得相关硬盘的句柄:
// Gets a handle to the physical disk
IntPtr hDisk = CreateFile(string.Format("\\.\PhysicalDrive{0}", diskNumber),
GenericRead,
Read | Write,
0,
OpenExisting,
0,
IntPtr.Zero);
现在,这是你必须了解的关于你的文件系统的部分。。。对于NTFS文件系统,您必须了解主文件表的概念。事实上,这很难。对于FAT文件系统,这不那么复杂,但仍然需要研究FS一段时间。从维基百科开始。
从您使用CreateFile
获得的句柄中,您现在将逐字节(实际上是逐扇区)读取(原始访问)字节到磁盘中,以使用ReadFile
获得您想要的信息。
// Used to read in a file
[DllImport("kernel32.dll")]
public static extern bool ReadFile(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToRead,
ref uint lpNumberOfBytesRead,
IntPtr lpOverlapped);
// Used to set the offset in file to start reading
[DllImport("kernel32.dll")]
public static extern bool SetFilePointerEx(
IntPtr hFile,
long liDistanceToMove,
ref long lpNewFilePointer,
uint dwMoveMethod);
// Set offset
int bufferSize = 512;
byte[] buffer = new byte[bufferSize];
SetFilePointerEx(
hDisk,
offset,
ref pt,
FileBegin);
// Read a whole sector
// Note that you can't read less than a whole sector of your physical disk. Usually it's 512 bytes,
// but you'll have to retrieve this information from the disk geometry. If you're interested, I can provide you
// some code. It requires the use of the IOCTL_DISK_GET_DRIVE_GEOMETRY control code.
uint read = 0;
ReadFile(
hDisk,
buffer,
bufferSize,
ref read,
IntPtr.Zero);
对于NTFS,首先要获得MFT的起始扇区。。。。然后您必须"解析"MFT并查找已删除的文件。。。
我不会在这里解释整个过程。有关示例,请参阅此链接。
祝你好运:)
现在您可能想要使用一个已经完成所有这些工作的第三方应用程序,并从您自己的程序中使用它(如注释中所述的命令行工具)