删除包含非空子目录和文件的目录
如何删除包含一些文件和一些非空子目录的目录。我试过SHFileOperation Function。它在Windows 7中有一些兼容性问题。我试过IFileOperation Interface。但它在Windows XP中不兼容。 后来我曾尝试以下代码的建议通过David Heffernan:删除包含非空子目录和文件的目录
procedure TMainForm.BitBtn01Click(Sender: TObject);
var
FileAndDirectoryExist: TSearchRec;
ResourceSavingPath : string;
begin
ResourceSavingPath := (GetWinDir) + 'Web\Wallpaper\';
if FindFirst(ResourceSavingPath + '\*', faAnyFile, FileAndDirectoryExist) = 0 then
try
repeat
if (FileAndDirectoryExist.Name <> '.') and (FileAndDirectoryExist.Name <> '..') then
if (FileAndDirectoryExist.Attr and faDirectory) <> 0 then
//it's a directory, empty it
ClearFolder(ResourceSavingPath +'\' + FileAndDirectoryExist.Name, mask, recursive)
else
//it's a file, delete it
DeleteFile(ResourceSavingPath + '\' + FileAndDirectoryExist.Name);
until FindNext(FileAndDirectoryExist) <> 0;
//now that this directory is empty, we can delete it
RemoveDir(ResourceSavingPath);
finally
FindClose(FileAndDirectoryExist);
end;
end;
但它不会在编译提误差未声明的标识符ClearFolder,面具和递归。我的要求是“如果WALLPAPER文件夹下存在任何子文件夹,它将被删除”。同一个子文件夹可能包含任意数量的非空子文件夹或文件。
那么,对于初学者,SHFileOperation
在Windows 7或Windows 8上没有兼容性问题。是的,现在推荐您使用IFileOperation
来代替。但是如果你想支持XP这样的老式操作系统,那么你可以并且应该只需要拨打SHFileOperation
。它工作并将继续工作。在Windows 7和Windows 8上使用它非常好,如果它从Windows删除,我会戴上帽子。微软竭尽全力保持向后兼容性。所以,在我看来,SHFileOperation
是您的最佳选择。
基于您的FindFirst
的方法失败,因为您需要将它放在单独的函数中以允许递归。我在其他答案中发布的代码不完整。下面是一个完整的版本:
procedure DeleteDirectory(const Name: string);
var
F: TSearchRec;
begin
if FindFirst(Name + '\*', faAnyFile, F) = 0 then begin
try
repeat
if (F.Attr and faDirectory <> 0) then begin
if (F.Name <> '.') and (F.Name <> '..') then begin
DeleteDirectory(Name + '\' + F.Name);
end;
end else begin
DeleteFile(Name + '\' + F.Name);
end;
until FindNext(F) <> 0;
finally
FindClose(F);
end;
RemoveDir(Name);
end;
end;
这删除目录及其内容。您需要遍历顶层目录,然后为您找到的每个子目录调用此函数。
最后,我已经实现了下面的代码:
uses
ShellAPI;
...
...
function GetWinDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory);
end;
...
...
procedure DeleteDirectory(const DirName: string);
var
FileFolderOperation: TSHFileOpStruct;
begin
FillChar(FileFolderOperation, SizeOf(FileFolderOperation), 0);
FileFolderOperation.wFunc := FO_DELETE;
FileFolderOperation.pFrom := PChar(ExcludeTrailingPathDelimiter(DirName) + #0);
FileFolderOperation.fFlags := FOF_SILENT or FOF_NOERRORUI or FOF_NOCONFIRMATION;
SHFileOperation(FileFolderOperation);
end;
...
...
procedure TMainForm.BitBtn01Click(Sender: TObject);
begin
DeleteDirectory((GetWinDir) + '\Web\Wallpapers\');
end
...
...
请不要提关于“TrailingPathDelimiter”什么,我特意来实现。我成功地解决了一个问题,即在Windows XP的情况下文件或文件夹成功删除而没有进入“回收站”,但是在Vista和更高版本的情况下,这些文件会转到“回收站”,而我没有任何选项在Vista或更高版本的情况下直接删除而不发送到“回收站”。
这是一个非常完整的功能,可以同时处理文件和文件夹。 它允许您指定以下参数:
- DeleteToRecycle
- ShowConfirm
- TotalSilence
{------------------ ---------------------------------------------
DELETE FILE
删除文件/文件夹到RecycleBin。
------------------------------------------------ ----------------}
function RecycleItem(CONST ItemName: string; CONST DeleteToRecycle: Boolean= TRUE; CONST ShowConfirm: Boolean= TRUE; CONST TotalSilence: Boolean= FALSE): Boolean;
VAR
SHFileOpStruct: TSHFileOpStruct;
begin
FillChar(SHFileOpStruct, SizeOf(SHFileOpStruct), #0);
SHFileOpStruct.wnd := Application.MainForm.Handle; { Others are using 0. But Application.MainForm.Handle is better because otherwise, the 'Are you sure you want to delete' will be hidden under program's window }
SHFileOpStruct.wFunc := FO_DELETE;
SHFileOpStruct.pFrom := PChar(ItemName+ #0);
SHFileOpStruct.pTo := NIL;
SHFileOpStruct.hNameMappings := NIL;
if DeleteToRecycle
then SHFileOpStruct.fFlags:= SHFileOpStruct.fFlags OR FOF_ALLOWUNDO;
if TotalSilence
then SHFileOpStruct.fFlags:= SHFileOpStruct.fFlags OR FOF_NO_UI
else
if NOT ShowConfirm
then SHFileOpStruct.fFlags:= SHFileOpStruct.fFlags OR FOF_NOCONFIRMATION;
Result:= SHFileOperation(SHFileOpStruct)= 0;
end;
@ user235 ....操作系统不会让一个正常的应用程序从c:\ windows删除文件! – Ampere 2014-04-08 11:31:43