Я пытаюсь создать простой пример использования IFileOperation для удаления файлов в данном каталоге, чтобы включить в ответ другой q для сравнения с другими методами.
Ниже приведен код моего MRE . Он успешно создает 1000 файлов в подкаталоге C: \ Temp, а затем пытается удалить их методом DeleteFiles
. Эта якобы «легкая» задача не удалась, но я точно не знаю, где она сходит с рельсов. Комментарии в коде показывают, что я ожидаю, и фактические результаты. В одном случае, вместо отмеченного исключения, я получил всплывающее окно с просьбой подтвердить удаление элемента с нечетным именем, которое, очевидно, представляло собой массив чисел, относящихся к элементу оболочки, но моя попытка захватить его с помощью Ctrl-Cне удалось;
Я вполне уверен, что пропустил один или два шага, неправильно использовал задействованные интерфейсы или оба. Мой вопрос: может ли кто-нибудь показать необходимые исправления в коде, чтобы получить IFileOperation.DeleteItems () для удаления файлов, о которых идет речь, так как я полностью разбираюсь в этом? Меня не интересуют альтернативные методы удаления этих файлов, использование интерфейсов оболочки или иное.
procedure TForm2.DeleteFiles;
var
iFileOp: IFileOperation;
iIDList : ItemIDList;
iItemArray : IShellItemArray;
iArray : Array[0..1] of ItemIDList;
Count : DWord;
begin
iFileOp := CreateComObject(CLSID_FileOperation) as IFileOperation;
iIDList := ILCreateFromPath(sPath)^;
// IFileOperation.DeleteItems seems to require am IShellItemArray, so the following attempts
// to create one
// The definition of SHCreateShellItemArrayFromIDLists
// seems to require a a zero-terminated array of ItemIDLists so the next steps
// attempt to create one
ZeroMemory(@iArray, SizeOf(iArray));
iArray[0] := iIDList;
OleCheck(SHCreateShellItemArrayFromIDLists(1, @iArray, iItemArray));
// Next test the number of items in iItemArray, which I'm expecting to be 1000
// seeing as the CreateFiles routine creats that many
OleCheck(iItemArray.GetCount(Count));
Caption := IntToStr(Count); // Duh, this shows Count to be 1, not the expected 1000
OleCheck(iFileOp.DeleteItems(iItemArray));
OleCheck( iFileOp.PerformOperations );
// Returns Exception 'No object for moniker'
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
DeleteFiles;
end;
procedure CreateFiles;
var
i : Integer;
SL : TStringList;
FileName,
FileContent : String;
begin
SL := TStringList.Create;
try
if not (DirectoryExists(sPath)) then
MkDir(sPath);
SL.BeginUpdate;
for i := 0 to 999 do begin
FileName := Format('File%d.Txt', [i]);
FileContent := Format('content of file %s', [FileName]);
SL.Text := FileContent;
SL.SaveToFile(sPath + '\' + FileName);
end;
SL.EndUpdate;
finally
SL.Free;
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
CreateFiles;
end;