Как восстановить файл из корзины с помощью C#?
Перемещение файлов в корзину и очистка корзины хорошо документированы, но как можно программно восстановить файл из корзины?
2 ответа
Кажется, не существует решения в чистом C#. Скорее всего, вам придется прибегнуть к P/Invoke. В этой статье представлено решение на C++ с использованием API SHFileOperation.
Единственное упоминание об этом, кроме упомянутой ранее ссылки на codeproject, которое я вижу, упоминает следующее:
Вызовите SHGetFolderLocation, передав CSIDL_BITBUCKET. Затем вы можете управлять этой папкой как обычно. Вам нужно будет создать взаимодействие для функции SHGetFolderLocation.
"CSIDL_BUCKET" является константой для виртуальной папки RecycleBin. Цитата взята отсюда и будет включать взаимодействие с оболочкой Windows. MSDN также упоминает, что эта функция устарела в пользу другой в Vista.
Надеюсь, что приведенный ниже код будет работать для восстановления файлов. Убедитесь, что вызовы STA поддерживаются только для вызовов оболочки
using System;
using System.Collections;
using System.Windows.Forms;
using System.IO;
using Shell32; //Reference Microsoft Shell Controls And Automation on the COM tab.
using System.Runtime.InteropServices;
using Microsoft.VisualBasic.FileIO;
using System.Threading;
private static void Restore(object param)
{
object[] args = (object[])param;
string filename = (string)args[0];
string filepath = (string)args[1];
Shl = new Shell();
Folder Recycler = Shl.NameSpace(10);
var c = Recycler.Items().Count;
var _recycler = Recycler.Items();
for (int i = 0; i < _recycler.Count; i++)
{
FolderItem FI = _recycler.Item(i);
string FileName = Recycler.GetDetailsOf(FI, 0);
if (Path.GetExtension(FileName) == "") FileName += Path.GetExtension(FI.Path);
//Necessary for systems with hidden file extensions.
string FilePath = Recycler.GetDetailsOf(FI, 1);
if (filepath == Path.Combine(FilePath, FileName))
{
DoVerb(FI, "ESTORE");
break;
}
}
}
private static bool DoVerb(FolderItem Item, string Verb)
{
foreach (FolderItemVerb FIVerb in Item.Verbs())
{
if (FIVerb.Name.ToUpper().Contains(Verb.ToUpper()))
{
FIVerb.DoIt();
return true;
}
}
return false;
}