Alexandre Severo
Alexandre Severo

Reputation: 19

Can't delete folder from a different partition

I'm having a problem when deleting folders that are on a different partition (E:/) from my software. I can delete files, using the DeleteFile function, but I'm not able to delete a folder using the code below:

function RemoveDirectory(strDir : String) : Boolean;
var
  SearchRec : TSearchRec;
  strFile   : String;
  nResult   : Integer;
begin
  try
    Result := false;

    nResult := FindFirst(strDir + '*', faAnyFile, SearchRec);

    while (nResult = 0) do
      begin
        if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
          begin
            strFile := strDir +  SearchRec.Name;

            if FileExists(strFile) then
              DeleteFile(strFile)
            else if DirectoryExists(strFile) then
              RemoveDirectory(strFile);
          end;
        nResult := FindNext(SearchRec);
      end;

    Result := RemoveDir(strDir);
  finally
    FindClose(SearchRec);
  end;
end;

With this code I can delete folders that are on the same partition from my software. Somebody knows what's going on? Is it because it's on a different partition?

Upvotes: 0

Views: 292

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595412

You are trying to remove directories while you still have open search handles. Since this is a recursive function, if the directory hierarchy is deep, you would have multiple search handles open at a time and that is a lot of system resources being used when the deeper folders are reached.

It is better to collect the immediate subfolders into a temp list, then you can close the current search handle before iterating that list. This way, there is ever only 1 search handle active at a time, and there is no search handle active when each folder is actually being deleted.

Try this:

function RemoveDirectory(strDir : String) : Boolean;
var
  SearchRec : TSearchRec;
  nResult,i : Integer;
  SubFolders: TStringList;
begin
  SubFolders := nil;
  try
    strDir := IncludeTrailingPathDelimiter(strDir);

    nResult := FindFirst(strDir + '*', faAnyFile, SearchRec);
    if (nResult = 0) then
    try
      repeat
        if (SearchRec.Attr and faDirectory) = 0 then
          DeleteFile(strDir + SearchRec.Name)
        else
        begin
          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
          begin
            if not Assigned(SubFolders) then SubFolders := TStringList.Create;
            SubFolders.Add(strDir + SearchRec.Name);
          end;
        end;
      until FindNext(SearchRec) <> 0;
    finally
      FindClose(SearchRec);
    end;

    if Assigned(SubFolders) then
    begin
      for i := 0 to SubFolders.Count-1 do
        RemoveDirectory(SubFolders[i]);
    end;
  finally
    SubFolders.Free;
  end;

  Result := RemoveDir(strDir);
end;

If this still fails, then someone else outside of your app/loop is actually using the directories, and you can use a tool like SysInternals Process Explorer to check that.

Upvotes: 4

LHristov
LHristov

Reputation: 1123

DeleteFile() is boolean function and you can receive only information was it successful or not. If you want more details return to the plain old Erase():

var f: file;

begin
  AssignFile(f,strFile);
  Erase(f);
end;

Here, if Erase() is not completed, an exception will be raised and you can receive more info, especially in the debugging phase.

Upvotes: -2

Related Questions