I simply need to check if a directory exists! But if the directory is "E:\Test" where E: is CD/DVD drive and there is no disk inserted on it, I see the following Delphi and Windows issues.
The first method:
function DirExists(Name: string): Boolean;
var
Code: Integer;
begin
Code := GetFileAttributesW(PChar(Name));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;
It gives Range Check Error
. I can't use {$RANGECHECKS OFF}
, {$RANGECHECKS ON}
blocks because:
$RANGECHECKS
option.Drive is not ready
instead Range Check Error
. But I simply need to check if directory exists without any error dialogs for user.The second method:
if DirectoryExists(Name, True) then ...
This function returns True
for non-existing E:\Test
directory on empty CD/DVD drive. So can't use it because it works incorrectly.
But then, how to find out if a directory exists?
P.S. I think the error exists with any CD/DVD drive. But I am using Windows 7 x64 on VMWare Fusion 5 under Mac OS X 10.8.4 with external CD/DVD drive.
You can just fix your function so that it doesn't cause range check errors:
function DirExists(Name: string): Boolean;
var
Code: DWORD;
begin
Code := GetFileAttributes(PChar(Name));
Result := (Code <> INVALID_FILE_ATTRIBUTES)
and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;
The range check errors are due to you mixing signed and unsigned types. Remy also points out the very useful trick to set compiler options and then restore to the prevailing state. That's a good trick to learn, but you don't need it here.
The XE3 implementation of DirectoryExists is modified to address the problem that you have encountered. So, if using XE3+ was an option, you should take it.
To suppress the system error dialogs call this at process startup:
procedure SetProcessErrorMode;
var
Mode: DWORD;
begin
Mode := SetErrorMode(SEM_FAILCRITICALERRORS);
SetErrorMode(Mode or SEM_FAILCRITICALERRORS);
end;
Doing this is best practise as described on MSDN:
Best practice is that all applications call the process- wide SetErrorMode function with a parameter of SEM_ FAILCRITICALERRORS at startup. This is to prevent error mode dialogs from hanging the application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With