formi
asked on
delphi: check if file is in use
I need to check if an exe-file is in use (started). I can not do this with the process-list because the program may be started from another pc in the network. I worked with the following procedure:
function FileIsInUse(aName : string) : boolean;
var
HFileRes : HFILE;
begin
if FileExists(aName) then
begin
HFileRes := CreateFile(pchar(aName), GENERIC_READ or
GENERIC_WRITE,0, nil,
OPEN_EXISTING,FILE_ATTRIBU TE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
_lclose(HFileRes);
end
else
Result := false;
end;
The problem is when the exe-file is write-protected (as it is for non-administrators) I always get "true" for this function. Are there other possibilities to check this?
Thanks in advance, Peter
function FileIsInUse(aName : string) : boolean;
var
HFileRes : HFILE;
begin
if FileExists(aName) then
begin
HFileRes := CreateFile(pchar(aName), GENERIC_READ or
GENERIC_WRITE,0, nil,
OPEN_EXISTING,FILE_ATTRIBU
Result := (HFileRes = INVALID_HANDLE_VALUE);
_lclose(HFileRes);
end
else
Result := false;
end;
The problem is when the exe-file is write-protected (as it is for non-administrators) I always get "true" for this function. Are there other possibilities to check this?
Thanks in advance, Peter
Here's a shorter example:
function IsFileInUse(FileName: TFileName): Boolean;
var
HFileRes: HFILE;
begin
Result := False;
if not FileExists(FileName) then Exit;
HFileRes := CreateFile(PChar(FileName) ,
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;
{Example:}
procedure TForm1.Button1Click(Sender : TObject);
begin
if IsFileInUse('c:\windows\no tepad.exe' ) then
ShowMessage('Notepad is in use.');
else
ShowMessage('Notepad not in use.');
end;
function IsFileInUse(FileName: TFileName): Boolean;
var
HFileRes: HFILE;
begin
Result := False;
if not FileExists(FileName) then Exit;
HFileRes := CreateFile(PChar(FileName)
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;
{Example:}
procedure TForm1.Button1Click(Sender
begin
if IsFileInUse('c:\windows\no
ShowMessage('Notepad is in use.');
else
ShowMessage('Notepad not in use.');
end;
ASKER
@Johnices: that is the procedure I have problems with ...
@thiagoblimeira: I didn't test it but if I don't have the rights to write to the file I have no chance to change the attribute! So this can't be the solution.
@thiagoblimeira: I didn't test it but if I don't have the rights to write to the file I have no chance to change the attribute! So this can't be the solution.
@formi,
I should learn to read an entire post before I jump in with some solution. Sorry about that!
My guess is that you are using Vista or Windows 7?
You may have to get around UAC if that is the case and run your app as an administrator or request privilege elevations by using a proper manifest.
If this is XP or under.... no other way that I know of other than to ensure your application has and runs under admin privileges.
John
I should learn to read an entire post before I jump in with some solution. Sorry about that!
My guess is that you are using Vista or Windows 7?
You may have to get around UAC if that is the case and run your app as an administrator or request privilege elevations by using a proper manifest.
If this is XP or under.... no other way that I know of other than to ensure your application has and runs under admin privileges.
John
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ok, I think there is no better solution, but I'll do it another way: I'll open a tempoary textfile if I start program x. If I start program y I'll try to delete this file. If this is not possible I know that program x is running. With your solution if program x crashes I'll never be able to start program y.
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(Fi
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)
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(fN
end; (*SetAttr*)
begin //IsFileInUse
if CheckAttributes(fName, 'R') then
begin
Result := False;
if not FileExists(fName) then exit;
if MessageDlg(ExtractFileName
beginb
Result := True;
Exit;
end;
end;
SetFileAttributes(PChar(fN
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