rng
asked on
Delete files ("C:\Temp\*.*" ), how??
Hello,
I would like to delete 'C:\Temp\*.*' permanently (without sending to recycle bin) by delphi's code.
DeleteFile doesn't work for wildcards. Which function can I use ?
Thanks.
rng
I would like to delete 'C:\Temp\*.*' permanently (without sending to recycle bin) by delphi's code.
DeleteFile doesn't work for wildcards. Which function can I use ?
Thanks.
rng
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
https://www.experts-exchange.com/questions/20624939/How-to-EMPTY-a-directory.html
ASKER
DeleteFile is the only command which can delete files ??
I think there is a command that can accept wildcards.
Thanks.
rng
I think there is a command that can accept wildcards.
Thanks.
rng
you may use the SHFileOperation - API
guess someone can provide a sample, or?
i myself -> no time, no equipment
meikl ;-)
guess someone can provide a sample, or?
i myself -> no time, no equipment
meikl ;-)
a sample you could get here
https://www.experts-exchange.com/questions/20624939/How-to-EMPTY-a-directory.html#8576619
https://www.experts-exchange.com/questions/20624939/How-to-EMPTY-a-directory.html#8576619
DeleteFile is indeed the only function in Delphi that deletes files without using the recycle bin. Unless you want to use the SHFileOperation() function in the ShellAPI unit.
uses ShellAPI;
var
FileOp: TSHFileOpStruct;
begin
FileOp.Wnd := GetDesktopWindow;
FileOp.wFunc := FO_DELETE;
FileOp.pFrom := 'C:\Temp\*.*'#0;
FileOp.pTo := nil;
FileOp.fFlags := FOF_NOCONFIRMATION;
SHFileOperation( FileOp );
end;
Above code will do the same, using a wildcard. It will NOT move them to the recycle bin. But personally, I just dislike this method since it invokes the shell to delete the files. It will also show a dialog box unless you specify that it should not do this. And I just feel I don't have enough control with this function. Even error handling is a bit troublesome, since it will show a messagebox with an error text on an error, unless you add FOF_NOERRORUI to the flags. I also dislike the additional #0 that you have to add to the from parameter, because this function expects a list of names here, separated by a #0.
Then again, you could use:
FileOp.pFrom := 'C:\Temp\*.cfg'#0'C:\Temp\ *.dcu'#0'C :\Temp\*.d pr'#0'C:\T emp\*.dfm' #0'C:\Temp \*.pas'#0;
to delete just multiple files with different filemasks. Makes it a bit more powerful than my first solution. So sometimes it does have it's advantages. But in general I just dislike it.
And it's about as many lines of code as the other solution...
uses ShellAPI;
var
FileOp: TSHFileOpStruct;
begin
FileOp.Wnd := GetDesktopWindow;
FileOp.wFunc := FO_DELETE;
FileOp.pFrom := 'C:\Temp\*.*'#0;
FileOp.pTo := nil;
FileOp.fFlags := FOF_NOCONFIRMATION;
SHFileOperation( FileOp );
end;
Above code will do the same, using a wildcard. It will NOT move them to the recycle bin. But personally, I just dislike this method since it invokes the shell to delete the files. It will also show a dialog box unless you specify that it should not do this. And I just feel I don't have enough control with this function. Even error handling is a bit troublesome, since it will show a messagebox with an error text on an error, unless you add FOF_NOERRORUI to the flags. I also dislike the additional #0 that you have to add to the from parameter, because this function expects a list of names here, separated by a #0.
Then again, you could use:
FileOp.pFrom := 'C:\Temp\*.cfg'#0'C:\Temp\
to delete just multiple files with different filemasks. Makes it a bit more powerful than my first solution. So sometimes it does have it's advantages. But in general I just dislike it.
And it's about as many lines of code as the other solution...
ASKER
I am a bit confused. Actually I am new to delphi and I thought deleting files is just a simple thing....
Could you provide a simple and work for sure solution ?
Thanks.
rng
Could you provide a simple and work for sure solution ?
Thanks.
rng
Well, both examples I've given will work if used correctly. You already have two examples. The problem is that Delphi does NOT have a simple function for deleting files using a wildcard. You would have to create that function yourself.
The problem isn't Delphi, btw. It's just the Windows API that just lacks this kind of functionality. My first example is more reliable, the second version just uses the shell (explorer) to delete files permanently.
The problem isn't Delphi, btw. It's just the Windows API that just lacks this kind of functionality. My first example is more reliable, the second version just uses the shell (explorer) to delete files permanently.
ASKER
Ok, I will try it myself and let you know the result.
BTW, why do you think it is no good to use the shell to delete files??
Thanks.
rng
BTW, why do you think it is no good to use the shell to delete files??
Thanks.
rng
I just dislike to use the shell functions because they take away a bit of the control I have. With my first solution I could check the return value of DeleteFile since it's a boolean function. If the deletion failed, I could retrieve extended error information by checking SysErrorMessage(GetLastErr or) and add this string result to a stringlist that logs all errors while I just continu to delete all other files. Once I'm done deleting I could display the user a list of files that could not be deleted.
With the shell function I won't be able to get the same level of error handling...
I dislike the lack of control you have. Furthermore, you have to make sure to use the right flags and make sure the filename ends with a #0 at the end. (Actually, two #0 characters but since I assign the value to a PChar type, Delphi will add the second one for me.) The shell function is a bit too complicated to my liking since it can also be used to move or copy or rename multiple files. I don't like functions that are overloaded this much... One mistake and this function might do something unexpected.
With the shell function I won't be able to get the same level of error handling...
I dislike the lack of control you have. Furthermore, you have to make sure to use the right flags and make sure the filename ends with a #0 at the end. (Actually, two #0 characters but since I assign the value to a PChar type, Delphi will add the second one for me.) The shell function is a bit too complicated to my liking since it can also be used to move or copy or rename multiple files. I don't like functions that are overloaded this much... One mistake and this function might do something unexpected.
About that SHFileOperation call: I'd add FOF_FILESONLY to the flags if I don't want any subfolders to be deleted also:
FileOp.fFlags := FOF_NOCONFIRMATION or FOF_FILESONLY or FOF_SILENT;
Otherwise (as Workshop_Alex already pointed out ;-) you might experience unexpected results.
Regards, Geo
FileOp.fFlags := FOF_NOCONFIRMATION or FOF_FILESONLY or FOF_SILENT;
Otherwise (as Workshop_Alex already pointed out ;-) you might experience unexpected results.
Regards, Geo
Geo is right. You must make sure you use the right options. One bug could do more damage than you would expect...
ASKER
Hi Alex,
I have tried your 1st code, it works great.
But it showed two warning messages during compile:
[Warning] Main.pas(917): Symbol 'faSysFile' is specific to a platform
[Warning] Main.pas(917): Symbol 'faHidden' is specific to a platform
Do you know how to get rid of them ?
Thanks.
rng
I have tried your 1st code, it works great.
But it showed two warning messages during compile:
[Warning] Main.pas(917): Symbol 'faSysFile' is specific to a platform
[Warning] Main.pas(917): Symbol 'faHidden' is specific to a platform
Do you know how to get rid of them ?
Thanks.
rng
Well, simple. Delphi warns you that those values are invalid if you're going to compile your project for .NET so what you have to do is just disable the platform dependency warnings. :-) Or just ignore them. I don't think you need to use faSysFile, though, unless you want to exclude them too... faAnyfile-faDirectory-faSy sFile would exclude folders AND system files.
ASKER
> compile your project for .NET ??
I am using Delphi 7, not Delphi for .NET, why will it show this warning?
> I don't think you need to use faSysFile
Yes, I think it is unsafe to delete system files, so I exclude them.
Thanks.
rng
I am using Delphi 7, not Delphi for .NET, why will it show this warning?
> I don't think you need to use faSysFile
Yes, I think it is unsafe to delete system files, so I exclude them.
Thanks.
rng
Well, Delphi 7 has some additional warnings that you can disable with the project options. The reason for this is because Delphi 7 wants to make developers aware of possible compatibility problems when you upgrade to Delphi 8. These are mostly pointer-related or related to some other functionality that are defined as being platform-dependant.
It's not just for .NET that Delphi includes these warnings. It's also used in case you want to create code that also needs to compile with Kylix. Am using Delphi 5 right now so can't look for which settings you need to turn off to remove these platform dependency warnings. You don't need to be warned about them because you're only compiling for a single platform.
(I wonder how Borland has solved this in Delphi 2005, which should be available on the market around now...)
It's not just for .NET that Delphi includes these warnings. It's also used in case you want to create code that also needs to compile with Kylix. Am using Delphi 5 right now so can't look for which settings you need to turn off to remove these platform dependency warnings. You don't need to be warned about them because you're only compiling for a single platform.
(I wonder how Borland has solved this in Delphi 2005, which should be available on the market around now...)
ASKER
> You don't need to be warned about them because you're only compiling for a single platform.
"single platform" means all existing Windows, right ?
Thanks for your info.
rng
"single platform" means all existing Windows, right ?
Thanks for your info.
rng
Yep. All existing windows versions. Or all existing Linux/BSD versions if you use Kylix. Or all .NET versions if you use Delphi 8 for .NET. Delphi is supported on three platforms now, although it seems that the Linux support is slowly disappearing again.
ASKER
Ok, thanks again!!
rng
rng