myleseven
asked on
Delete a folder recursivly
Hi there I am trying to work on a solution to delete a folder recursivly.
I have tried various solutions that have been posted up on the Net but none seem to work for me.
At the moment I have a solution that delete all files inside a folder and subfolders but does not delete folders.
I am not sure why.
The function I am using to remove folders is called RemoveDir.
It seems to be temproamental, that means that sometimes it deletes thema nd sometimes it does not.
I have wondered if this is because the folders maight be readonly.
I tried DeleteFile and this did not seem to work for Folders.
Here is an example that I found on the Net. It is typical of solutions that I am finding but they don't seem to work for me at all.
procedure DeleteFiles(sDir: string);
//Deletes all files in sDir
var
MySearch: TSearchRec;
begin
FindFirst(sDir+'\*.*', faAnyFile, MySearch);
if (MySearch.Name<>'.')and
(MySearch.Name<>'..') then
DeleteFile(sDir+MySearch.N ame);
while FindNext(MySearch)=0 do
begin
if (MySearch.Name<>'.')and
(MySearch.Name<>'..') then
DeleteFile(sDir + '\' +MySearch.Name);
end;
end;
Here is a solution that I am working on.
Here is the one that I am using:
procedure TfrmUpdate.aDeleteFiles(sD ir: string);
//Deletes all files in sDir
var
MySearch: TSearchRec;
sFile: string;
sName : string;
begin
sDir := IncludeTrailingBackslash(s Dir);
FindFirst(sDir+ '*.*', faAnyFile, MySearch);
sName := MySearch.Name;
if (sName<>'.')and (sName<>'..') then
begin
sFile := sDir+MySearch.Name;
RemoveDir(sFile);
end;
while FindNext(MySearch)=0 do
begin
sName := MySearch.Name;
if (MySearch.Name<>'.')and (MySearch.Name<>'..') then
begin
sFile := sDir+MySearch.Name;
if MySearch.Attr = faDirectory then
begin
if not RemoveDir(sFile) then adeleteFiles(sFile);
end else
begin
DeleteFile(sFile);
end;
end else
begin
sFile := trim((GoBackFilePath2(sFil e,1)));
RemoveDir(sFile);
end;
end;
end;
function GoBackFilePath2(sFilepath: string; iCount : integer):string;
{
Overhaul:
Date: 24/04/2006
Purpose: Now it will go back as many folders as indicated
}
var
i,y : integer;
sTemp : string;
begin
if sFilepath <> '' then
begin
sTemp := ReverseString(sFilepath);
y := 0;
for i := 1 to iCount do
begin
y := PosEx('\',sTemp,y+1);
end;
result := MidStr(sFilePath,0,(length (sFilePath )-y));
end else
begin
result := c_Null;
end;
end;
The problem is I can't seem to find a function that will reliably delete a folder even if it is empty?!?
Can any one help me?
Kind regards
Myles
I have tried various solutions that have been posted up on the Net but none seem to work for me.
At the moment I have a solution that delete all files inside a folder and subfolders but does not delete folders.
I am not sure why.
The function I am using to remove folders is called RemoveDir.
It seems to be temproamental, that means that sometimes it deletes thema nd sometimes it does not.
I have wondered if this is because the folders maight be readonly.
I tried DeleteFile and this did not seem to work for Folders.
Here is an example that I found on the Net. It is typical of solutions that I am finding but they don't seem to work for me at all.
procedure DeleteFiles(sDir: string);
//Deletes all files in sDir
var
MySearch: TSearchRec;
begin
FindFirst(sDir+'\*.*', faAnyFile, MySearch);
if (MySearch.Name<>'.')and
(MySearch.Name<>'..') then
DeleteFile(sDir+MySearch.N
while FindNext(MySearch)=0 do
begin
if (MySearch.Name<>'.')and
(MySearch.Name<>'..') then
DeleteFile(sDir + '\' +MySearch.Name);
end;
end;
Here is a solution that I am working on.
Here is the one that I am using:
procedure TfrmUpdate.aDeleteFiles(sD
//Deletes all files in sDir
var
MySearch: TSearchRec;
sFile: string;
sName : string;
begin
sDir := IncludeTrailingBackslash(s
FindFirst(sDir+ '*.*', faAnyFile, MySearch);
sName := MySearch.Name;
if (sName<>'.')and (sName<>'..') then
begin
sFile := sDir+MySearch.Name;
RemoveDir(sFile);
end;
while FindNext(MySearch)=0 do
begin
sName := MySearch.Name;
if (MySearch.Name<>'.')and (MySearch.Name<>'..') then
begin
sFile := sDir+MySearch.Name;
if MySearch.Attr = faDirectory then
begin
if not RemoveDir(sFile) then adeleteFiles(sFile);
end else
begin
DeleteFile(sFile);
end;
end else
begin
sFile := trim((GoBackFilePath2(sFil
RemoveDir(sFile);
end;
end;
end;
function GoBackFilePath2(sFilepath:
{
Overhaul:
Date: 24/04/2006
Purpose: Now it will go back as many folders as indicated
}
var
i,y : integer;
sTemp : string;
begin
if sFilepath <> '' then
begin
sTemp := ReverseString(sFilepath);
y := 0;
for i := 1 to iCount do
begin
y := PosEx('\',sTemp,y+1);
end;
result := MidStr(sFilePath,0,(length
end else
begin
result := c_Null;
end;
end;
The problem is I can't seem to find a function that will reliably delete a folder even if it is empty?!?
Can any one help me?
Kind regards
Myles
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
uses ShellAPI;
...
var
FileOp : ShFileOpStruct;
begin
ZeroMemory(@FileOp, sizeof(FileOp));
with FileOp do begin
Wnd := handle;
wFunc := fo_delete;
pFrom := 'D:\documents\Projects\MEm ulator\adf '#0#0; // two #0 have to be at the end
fFlags := fof_noconfirmation or fof_silent;
end;
if SHFileOperation(FileOp) <> 0 then ShowMessage('error');
end;
...
var
FileOp : ShFileOpStruct;
begin
ZeroMemory(@FileOp, sizeof(FileOp));
with FileOp do begin
Wnd := handle;
wFunc := fo_delete;
pFrom := 'D:\documents\Projects\MEm
fFlags := fof_noconfirmation or fof_silent;
end;
if SHFileOperation(FileOp) <> 0 then ShowMessage('error');
end;
ASKER
Thank you both for your help - Imthiyaz_ph and ZhaawZ
but I was looking for a recursive solution.
ciuly - Your solution worked perfectlly!
I like the little code replacement you used for IncludeTrailingBackslash
Do you mind if I ask you what does this line mean:
if findfirst(dir+'*.*',faAnyF ile {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON} ,r)=0 then
I mean how come youneeded to use the : {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON}?
Also why did you need to specify:
and faDirectory = faDirectory
And how come your use of RemoveDir worked but mine did not even though with my procedure when I called RemoveDir the folder was empty?
Kind regards
Myles
but I was looking for a recursive solution.
ciuly - Your solution worked perfectlly!
I like the little code replacement you used for IncludeTrailingBackslash
Do you mind if I ask you what does this line mean:
if findfirst(dir+'*.*',faAnyF
I mean how come youneeded to use the : {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON}?
Also why did you need to specify:
and faDirectory = faDirectory
And how come your use of RemoveDir worked but mine did not even though with my procedure when I called RemoveDir the folder was empty?
Kind regards
Myles
SHFileOperation() is a ShellAPI function that allows to do many things with files/folders, includilg *recursive* deleting. In my example will be deleted directory "D:\documents\Projects\MEm ulator\adf " and all directories/subdirectories /files that are in it.
>> Also why did you need to specify:
>> and faDirectory = faDirectory
It was "r.Attr and faDirectory = faDirectory" - it checks if it is a directory or a file. Then he uses DeleteDirectory() if it is a directory or DeleteFile() if it is a file.
>> and faDirectory = faDirectory
It was "r.Attr and faDirectory = faDirectory" - it checks if it is a directory or a file. Then he uses DeleteDirectory() if it is a directory or DeleteFile() if it is a file.
ASKER
Thanks ZHaawZ
in regards to your mentioning about the ShellAPI function. It may be that you can do recursive deleting with this function but I wanted to actually see how a recursive deleting function looked like. That is why I likeed ciuly's example.
also
in regard to and faDirectory = faDirectory
why could we not simply say
if r.Attr = faDirectory
?
kind regards
Myles :)
in regards to your mentioning about the ShellAPI function. It may be that you can do recursive deleting with this function but I wanted to actually see how a recursive deleting function looked like. That is why I likeed ciuly's example.
also
in regard to and faDirectory = faDirectory
why could we not simply say
if r.Attr = faDirectory
?
kind regards
Myles :)
r.Attr can consist of several "1" bits. "And" operation checks if specific bits are set.
Here's an example with binary (not hex) values:
00010000 - faDirectory
00000001 - faReadOnly
00000010 - faHidden
if r.Attr is 00010011, it means that it is read-only hidden directory. "if r.Attr = faDirectory" will return false, because 00010011 <> 00010000. Therefore you use "and" operation (00010011 and 00010000 = 00010000) and then compare it to faDirectory
Here's an example with binary (not hex) values:
00010000 - faDirectory
00000001 - faReadOnly
00000010 - faHidden
if r.Attr is 00010011, it means that it is read-only hidden directory. "if r.Attr = faDirectory" will return false, because 00010011 <> 00010000. Therefore you use "and" operation (00010011 and 00010000 = 00010000) and then compare it to faDirectory
ASKER
so this means that if r.Attr is only a directory and is not hidden or read only.
therefore if I tried this on a hidden or a readonly folder it will not delete it?
therefore if I tried this on a hidden or a readonly folder it will not delete it?
if you compare "r.attr = faDirectory", then it should return "false" on hidden and/or read-only folder
if you compare "r.attr and faDirectory = faDirectory", then it should return "true" on all folders
if you compare "r.attr and faDirectory = faDirectory", then it should return "true" on all folders
ASKER
ok I sort of understand
how about this code:
if findfirst(dir+'*.*',faAnyF ile {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON} ,r)=0 then
What does this line mean and why do we need it {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON}?
how about this code:
if findfirst(dir+'*.*',faAnyF
What does this line mean and why do we need it {$WARNINGS OFF}-faVolumeID-faSymLink {$WARNINGS ON}?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hey thanks for all your help Zhaawz,
I will split the points between you and ciuly.
Ciuly gave me the answer I was looking for but i will reward you with more points because of your efforts :)
kind regards
Myles
I will split the points between you and ciuly.
Ciuly gave me the answer I was looking for but i will reward you with more points because of your efforts :)
kind regards
Myles
glad to help ;]
sorry for not stepping in, I'm in GMT+2 :) (so it's 9 am here now) thank you ZhaawZ for taking the lead and doing a pretty good explanation :)
(btw, I'm in GMT+2 too, heh.. well, this was a long night)
http://delphi.about.com/cs/adptips1999/a/bltip1199_2.htm
It shows how to delete a folder and its contents using shellapi.
Regards
Imthiyaz