2012-01-11 2 views
10

Можно создать дубликат:
How do I restore a file from the recycle bin using C#?
Recovering deleted file on windowsC# классы для восстановления файлов?

Я работаю над приложением, которое предназначено для восстановления удаленных файлов из системы (и те из корзины и те, кто уже опустел от корзины, но все еще понятные) и отформатированные диски. Я решил использовать C# как язык, но мне трудно найти классы, которые справляются с этой проблемой. Кто-нибудь знает какие-либо классы/методы для поиска удаленных файлов, получения их или любых учебных пособий или помогает в этом вопросе. У меня мало опыта в этом вопросе, поэтому любая помощь будет очень оценена.

+1

Мое предположение: вы закончите с одним из многих восстановленных приложений с интерфейсом командной строки. – CodingBarfield

+0

Я не уверен, что C# это сделает, поскольку вам, вероятно, понадобятся некоторые API-интерфейсы низкого уровня для чтения данных с диска из определенного места. Для этого вы, скорее всего, будете использовать C или C++. – oleksii

+0

Связано: [Восстановление удаленных файлов в windows] (http://stackoverflow.com/questions/2837307/recovering-deleted-file-on-windows), [Как восстановить файл с помощью C#?] (Http: // stackoverflow.com/questions/1352550/how-can-i-undelete-a-file-using-c), [Как открыть каталог с CreateFile в C# для проверки удаленных записей?] (http://stackoverflow.com/questions/1344094/how-do-i-open-a-directory-with-createfile-in-c-sharp-to-review-deleted-entries) –

ответ

37

Нет встроенных классов, чтобы сделать то, что вы задали.

На самом деле, удаление файлов является сложным процессом и требует очень низкого уровня знаний о вашей файловой системе. Поэтому первое, что нужно сделать, это получить информацию о диске, который содержит файл, который вы хотите восстановить. В основном вы сначала хотите узнать свою файловую систему.

Вам придется использовать 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, вам нужно понять концепцию Master File Table. На самом деле, это довольно сложно. Для файловых систем FAT это менее сложно, но все же вам придется некоторое время изучать FS. Начните с wikipedia.

С помощью ручки, которую вы используете, 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 и ищет удаленные файлы ...

я выиграл Объясните весь процесс здесь. См. Пример this link.

Так что удачи с этим :)

Теперь вы, вероятно, захотите использовать приложения сторонних производителей, которые уже делает все эти вещи, и использовать его с вашей собственной программы (утилиты командной строки, как говорится в комментариях) ,

Смежные вопросы