The IsFileInUse Delphi function will return true if the file is locked for exclusive access. False is returned if the file does not exist.
Code "flow":
Two things need to be checked here: A) Is the file a READ-ONLY file? and B) Is the file in use?
The main point of the excercise is to check the files attributes for the READ-ONLY flag before doing the check for "in-use". If the file is READ-ONLY then offer the user the option to remove the READ-ONLY attribute so that processing can continue.
If the user wishes to remove the READ-ONLY attribute, the files attributes are cleared (set to NORMAL which is an exclusive attribute), and then whatever other attributes are restored.
uses StrUtils;
function IsFileInUse(fName : string) : boolean;
var
HFileRes : HFILE;
Res: string[6];
function CheckAttributes(FileNam: string; CheckAttr: string): Boolean;
var
fa: Integer;
begin
fa := GetFileAttributes(PChar(FileNam)) ;
Res := '';
if (fa and FILE_ATTRIBUTE_NORMAL) <> 0 then
begin
Result := False;
Exit;
end;
if (fa and FILE_ATTRIBUTE_ARCHIVE) <> 0 then
Res := Res + 'A';
if (fa and FILE_ATTRIBUTE_COMPRESSED) <> 0 then
Res := Res + 'C';
if (fa and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
Res := Res + 'D';
if (fa and FILE_ATTRIBUTE_HIDDEN) <> 0 then
Res := Res + 'H';
if (fa and FILE_ATTRIBUTE_READONLY) <> 0 then
Res := Res + 'R';
if (fa and FILE_ATTRIBUTE_SYSTEM) <> 0 then
Res := Res + 'S';
Result := AnsiContainsText(Res, CheckAttr) ;
end; (*CheckAttributes*)
procedure SetAttr(fName: string) ;
var
Attr: Integer;
begin
Attr := 0;
if AnsiContainsText(Res, 'A') then
Attr := Attr + FILE_ATTRIBUTE_ARCHIVE;
if AnsiContainsText(Res, 'C') then
Attr := Attr + FILE_ATTRIBUTE_COMPRESSED;
if AnsiContainsText(Res, 'D') then
Attr := Attr + FILE_ATTRIBUTE_DIRECTORY;
if AnsiContainsText(Res, 'H') then
Attr := Attr + FILE_ATTRIBUTE_HIDDEN;
if AnsiContainsText(Res, 'S') then
Attr := Attr + FILE_ATTRIBUTE_SYSTEM;
SetFileAttributes(PChar(fName), Attr) ;
end; (*SetAttr*)
begin //IsFileInUse
if CheckAttributes(fName, 'R') then
begin
Result := False;
if not FileExists(fName) then exit;
if MessageDlg(ExtractFileName(fName) + ' is a READ-ONLY file.' + #13#10 + 'Do you wish to clear the READ-ONLY flag???', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
beginb
Result := True;
Exit;
end;
end;
SetFileAttributes(PChar(fName), FILE_ATTRIBUTE_NORMAL) ;
SetAttr(fName) ;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) ;
Result := (HFileRes = INVALID_HANDLE_VALUE) ;
if not Result then CloseHandle(HFileRes) ;
end; //IsFileInUse
Delphi tips navigator:
» Convert a Drive Letter ("D") to a Drive Number (4) - as Used by Delphi's DiskFree function
« Get Enum information Using Delphi's RTTI

