What is holding a file?

Dear all,

If a doc file is in use by a program say MS Word, when I try to delete this file in Windows Explorer, I will get a message that this file is in use by Word like the screen below:

http://www.creightonbrown.geek.nz/Docs/ComputerSupport/Cannot%20Delete%20file.gif

How do I detect which program is holding a file in Delphi?

Regards,
Fox
foxvisionAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Wim ten BrinkSelf-employed developerCommented:
Well, it would be a difficult technique, where you have to enumerate all processes and then all filehandles within each process. Based upon the filehandle you must check to see if it's attached to the file you want to delete. If it is, then you've found one process that keeps it locked. (But there could be more!)
See http://www.sysinternals.com/ntw2k/freeware/handle.shtml for a tool that just shows which files are open by which process.

Unfortunately, there doesn't seem to be any source available and I don't have any useful source either...
0
sdmasonCommented:
I've got a partial solution (I can't see all processes) using Colin Wilson's code found at
http://www.wilsonc.demon.co.uk/d7fileanalyzer.htm
To build the application you also need to get his NT Low level utilities from
http://www.wilsonc.demon.co.uk/d7ntutils.htm
and the misc components.
http://www.wilsonc.demon.co.uk/d7miscunits.htm

// Function
uses
  NTDDK,
  unitNTHandles;

function FileUsedBy(const AFileName : TFileName; var UsedBy : TStringList) : integer;
var
  ASHandles                             : TSystemHandles;
  AFHandles                             : TSystemFileHandles;
  liIndex                               : integer;
  fhiTest                               : TFileHandleInfo;
begin
  Result := 0;
  UsedBy.Clear;

  ASHandles := TSystemHandles.Create;
  AFHandles := TSystemFileHandles.Create(ASHandles);
  try

    for liIndex := 0 to AFHandles.Count - 1 do
      begin
        fhiTest := AFHandles.FileHandle[liIndex];
        if Pos(AFileName, fhiTest.FileName) <> 0 then  // You may want to match the whole path or part of a path
          begin
            Inc(Result);
            UsedBy.Add(fhiTest.ProcessName);
          end;
      end;
  finally
    AFHandles.Free;
    ASHandles.Free;
  end;
end;

// Sample usage

procedure TForm1.btnTestClick(Sender : TObject);
var
  lsTestFile                            : string;
  lsUser                                : TStringList;
begin
  lsTestFile := 'source';
  lsUser := TStringList.Create;

  if FileUsedBy(lsTestFile, lsUser) <> 0 then
    ShowMessage('Used by ' +#13#10+  lsUser.Text);
  lsUser.Free;
end;

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.