2012-01-11 14 views
10

thể trùng lặp:
How do I restore a file from the recycle bin using C#?
Recovering deleted file on windowsC# lớp học để phục hồi các tập tin?

tôi đang làm việc trên một ứng dụng được thiết kế để khôi phục các file bị xóa từ hệ thống (cả những người từ Recycle Bin và những người đã làm trống từ thùng rác nhưng vẫn có thể hiểu được) và các ổ đĩa được định dạng. Tôi đã quyết định C# là ngôn ngữ, nhưng tôi gặp khó khăn trong việc tìm kiếm các lớp học giải quyết vấn đề này. Có ai biết bất kỳ lớp học/phương pháp để tìm các tập tin đã xóa, lấy chúng hoặc bất kỳ hướng dẫn hoặc giúp về vấn đề này. Tôi có ít kinh nghiệm về đề tài này nên mọi sự giúp đỡ sẽ được đánh giá cao.

+1

Tôi đoán bạn sẽ kết thúc với một trong nhiều ứng dụng phục hồi xung quanh bằng giao diện dòng lệnh. – CodingBarfield

+0

Tôi không chắc chắn C# sẽ làm điều này, vì bạn có thể sẽ cần một số API cấp thấp để đọc dữ liệu từ đĩa từ một vị trí cụ thể. Bạn có thể sẽ sử dụng C hoặc C++ cho điều đó. – oleksii

+0

Liên quan: [Khôi phục tập tin đã xóa trên cửa sổ] (http://stackoverflow.com/questions/2837307/recovering-deleted-file-on-windows), [Làm thế nào tôi có thể phục hồi một tập tin bằng C#?] (Http: // stackoverflow.com/questions/1352550/how-can-i-undelete-a-file-using-c), [Làm thế nào để mở một thư mục với CreateFile trong C# để kiểm tra các mục đã xóa?] (http://stackoverflow.com/câu hỏi/1344094/làm thế nào-do-i-mở-một-thư mục-với-createfile-in-c-sắc nét-to-kiểm tra-xóa-mục) –

Trả lời

37

Không có lớp học được cài sẵn để làm những gì bạn đã yêu cầu.

Thực tế, việc khôi phục tệp là một quá trình khó và đòi hỏi kiến ​​thức ở mức độ rất thấp về hệ thống tệp của bạn. Vì vậy, điều đầu tiên cần làm là lấy thông tin về ổ đĩa chứa tệp mà bạn muốn phục hồi. Về cơ bản bạn đầu tiên muốn biết hệ thống tập tin của nó.

Bạn sẽ phải sử dụng P/Gọi rất nhiều. Trước hết, hãy xử lý ổ đĩa bạn nhắm mục tiêu:

[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(); 

Khi bạn có tên hệ thống tệp, bạn sẽ phải đọc dữ liệu thô từ ổ đĩa theo cách thủ công. Những gì bạn sẽ đọc hoàn toàn phụ thuộc vào hệ thống tệp của ổ đĩa. Dù sao, bạn sẽ có để có được một xử lý để ổ cứng có liên quan cho rằng:

// Gets a handle to the physical disk 
IntPtr hDisk = CreateFile(string.Format("\\\\.\\PhysicalDrive{0}", diskNumber), 
    GenericRead, 
    Read | Write, 
    0, 
    OpenExisting, 
    0, 
    IntPtr.Zero); 

Bây giờ là phần bạn sẽ phải biết rất nhiều về hệ thống tập tin của bạn ... Đối với hệ thống tập tin NTFS, bạn sẽ phải hiểu khái niệm về Master File Table. Trên thực tế, điều đó khá khó. Đối với hệ thống tệp FAT, điều đó ít phức tạp hơn nhưng vẫn còn, bạn sẽ phải nghiên cứu FS trong một thời gian. Bắt đầu với wikipedia.

Từ tay cầm bạn đã sử dụng CreateFile, bây giờ bạn sẽ đọc (nguyên truy cập) byte mỗi byte (theo ngành theo ngành thực tế) vào đĩa để lấy thông tin bạn muốn sử dụng 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); 

Đối với NTFS, điều đầu tiên nó để có được khu vực bắt đầu của MFT .... sau đó bạn sẽ phải "phân tích" MFT và tìm kiếm các file bị xóa ...

tôi thắng không giải thích toàn bộ quá trình ở đây. Xem this link để biết ví dụ.

Vì vậy, chúc may mắn với điều đó :)

Bây giờ bạn có thể có thể muốn sử dụng một ứng dụng của bên thứ ba mà đã làm tất cả những thứ này và sử dụng nó từ chương trình riêng của mình (công cụ dòng lệnh như đã nói trong các ý kiến) .