Работа с корзиной из Delphi

Удаление в корзину:

function Recycle(const FileName: string): Boolean;
var
  FileOp: TSHFileOpStruct;
begin
  FillChar(FileOp, SizeOf(FileOp), 0);
  FileOp.Wnd    := 0;
  FileOp.wFunc  := FO_DELETE;
  FileOp.pFrom  := PChar(FileName+#0#0);
  FileOp.fFlags := FOF_ALLOWUNDO or FOF_NOERRORUI or FOF_SILENT;
  Result := (SHFileOperation(FileOp) = 0) and
            (not(FileOp.fAnyOperationsAborted));
end;

Перечислить файлы в корзине:

procedure RecycleInfo;
var
  pidl       : PItemIdList;
  Desktop,
  RecycleBin : IShellFolder;
  Fetched    : Cardinal;
  EnumL      : IEnumiDList;
  StrR       : StrRet;
  s          : string;
begin
  // Получаем указатель на корзину.
  SHGetSpecialFolderLocation(Application.Handle, CSIDL_BITBUCKET, pidl);
  // Получаем интерфейс рабочего стола.
  OleCheck(SHGetDesktopFolder(Desktop));
  // Получаем интерфейс корзины.
  OleCheck(Desktop.BindToObject(pidl, nil, IID_IShellFolder, Pointer(RecycleBin)));
  // Получаем список объектов в корзине.
  OleCheck(RecycleBin.EnumObjects(Application.Handle, 
                                  SHCONTF_FOLDERS or SHCONTF_NONFOLDERS  or SHCONTF_INCLUDEHIDDEN, 
                                  EnumL));
  // Перебираем объекты в списке.
  while (EnumL.Next(1, pidl, Fetched)= S_OK) do
  begin
    // Извлечём имя объекта (оно же - первоначальное расположение).
    RecycleBin.GetDisplayNameOf(pidl, SHGDN_NORMAL, StrR);
    case StrR.uType of
      STRRET_CSTR:   s := StrR.cStr;
      STRRET_OFFSET: s := StrR.pStr;
      STRRET_WSTR:   s := StrR.pOleStr;
    end;
    // Теперь в s у нас имя объекта. Можно с ним что-нибудь поделать.
  end;
end;

Восстановление из корзины по имени:

function Undelete(const aFileName: string): boolean;
var
    ppidl, Item    : PItemIDList;
    Desktop        : IShellFolder;
    RecycleBin     : IShellFolder2;
    RecycleBinEnum : IEnumIDList;
    Fetched        : Cardinal;
    StrR           :StrRet;
    s:string;
    Context: IContextMenu;
    AInvokeCommand: TCMInvokeCommandInfo;
begin
  result := false;
  // Получаем указатель на корзину.
  OleCheck(SHGetSpecialFolderLocation(Application.Handle,
    CSIDL_BITBUCKET, ppidl));
  // Получаем интерфейс на рабочий стол.
  OleCheck(SHGetDesktopFolder(Desktop));
  // Получаем интерфейс на корзину.
  OleCheck(Desktop.BindToObject(ppidl, nil,
    IID_IShellFolder2, RecycleBin));
  // Получаем список объектов в корзине.
  OleCheck(RecycleBin.EnumObjects(Application.Handle,
    SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN,
    RecycleBinEnum));

  // Ищем элемент по имени.
  while (RecycleBinEnum.Next(1, Item, Fetched) = S_OK) do
  begin
    // Получаем имя текущего элемента.
    RecycleBin.GetDisplayNameOf(Item,SHGDN_NORMAL, StrR);
    case StrR.uType of
      STRRET_CSTR  : s := StrR.cStr;
      STRRET_OFFSET: s := StrR.pStr;
      STRRET_WSTR  : s := StrR.pOleStr;
    end;

    if UpperCase(s) = UpperCase(aFileName) then
    begin
      // Получаем интерфейс контекстного меню.
      if RecycleBin.GetUIObjectOf(Application.Handle, 1, Item,
        IID_IContextMenu, nil, Pointer(Context)) = S_OK then
      begin
        // Формируем команду восстановления.
        FillMemory(@AInvokeCommand, SizeOf(AInvokeCommand), 0);
        with AInvokeCommand do
        begin
          cbSize := SizeOf(AInvokeCommand);
          hwnd := Application.Handle;
          lpVerb := 'undelete'; // строковая константа для операции над элементом...
          fMask := CMIC_MASK_FLAG_NO_UI;
          nShow := SW_SHOWNORMAL;
        end;
        // Выполняем команду.
        result := (Context.InvokeCommand(AInvokeCommand) = S_OK);
      end;
      break;
    end;
  end;
end;

Чтобы окончательно удалить элемент из корзины нужно аналогичным образом вызвать из контекстного меню команду delete.

Полная очистка корзины:

SHEmptyRecycleBin(Application.Handle, '', 0);
Метки: