Mega Code Archive

 
Categories / Delphi / Examples
 

Imitating DelTree

Title: Imitating DelTree Question: How can I delete a directory (with all its subdirectories)? Answer: DelTree ------- The command-line program DELTREE.EXE that comes with Windows removes a directory with all its files and subdirectories. To mimic this behaviour in Delphi we can use the following procedure that uses the FindFirst, FindNext and FindClose functions to perform the file and directory search: uses FileCtrl; procedure DelTree(const Directory: TFileName); var DrivesPathsBuff: array[0..1024] of char; DrivesPaths: string; len: longword; ShortPath: array[0..MAX_PATH] of char; dir: TFileName; procedure rDelTree(const Directory: TFileName); // Recursively deletes all files and directories // inside the directory passed as parameter. var SearchRec: TSearchRec; Attributes: LongWord; ShortName, FullName: TFileName; pname: pchar; begin if FindFirst(Directory + '*', faAnyFile and not faVolumeID, SearchRec) = 0 then begin try repeat // Processes all files and directories if SearchRec.FindData.cAlternateFileName[0] = #0 then ShortName := SearchRec.Name else ShortName := SearchRec.FindData.cAlternateFileName; FullName := Directory + ShortName; if (SearchRec.Attr and faDirectory) 0 then begin // It's a directory if (ShortName '.') and (ShortName '..') then rDelTree(FullName + '\'); end else begin // It's a file pname := PChar(FullName); Attributes := GetFileAttributes(pname); if Attributes = $FFFFFFFF then raise EInOutError.Create(SysErrorMessage(GetLastError)); if (Attributes and FILE_ATTRIBUTE_READONLY) 0 then SetFileAttributes(pname, Attributes and not FILE_ATTRIBUTE_READONLY); if Windows.DeleteFile(pname) = False then raise EInOutError.Create(SysErrorMessage(GetLastError)); end; until FindNext(SearchRec) 0; except FindClose(SearchRec); raise; end; FindClose(SearchRec); end; if Pos(#0 + Directory + #0, DrivesPaths) = 0 then begin // if not a root directory, remove it pname := PChar(Directory); Attributes := GetFileAttributes(pname); if Attributes = $FFFFFFFF then raise EInOutError.Create(SysErrorMessage(GetLastError)); if (Attributes and FILE_ATTRIBUTE_READONLY) 0 then SetFileAttributes(pname, Attributes and not FILE_ATTRIBUTE_READONLY); if Windows.RemoveDirectory(pname) = False then begin raise EInOutError.Create(SysErrorMessage(GetLastError)); end; end; end; // ---------------- begin DrivesPathsBuff[0] := #0; len := GetLogicalDriveStrings(1022, @DrivesPathsBuff[1]); if len = 0 then raise EInOutError.Create(SysErrorMessage(GetLastError)); SetString(DrivesPaths, DrivesPathsBuff, len + 1); DrivesPaths := Uppercase(DrivesPaths); len := GetShortPathName(PChar(Directory), ShortPath, MAX_PATH); if len = 0 then raise EInOutError.Create(SysErrorMessage(GetLastError)); SetString(dir, ShortPath, len); dir := Uppercase(dir); rDelTree(IncludeTrailingBackslash(dir)); end; Sample calls ------------ This code will remove the directory C:\TEMP\A123: DelTree('C:\TEMP\A123'); And this code will wipe out the diskette in drive A: DelTree('A:'); // or DelTree('A:\'); WARNING ------- The procedure DelTree presented here erases files and directories, and they might not be recoverable later. It is provided in the belief that it is useful, but you use it at our own risk.