We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now


Monitor File usage

moose032797 asked
Medium Priority
Last Modified: 2010-04-06
How do I tell / monitor what files are open / closed
- regardless of the application that opened / closed them ?

If I use FileOpen, I get horrid windows sharing violation
messages.  i.e. How do I gather data similar to
CleanSweep's File Usage Monitor ?

I need to know what (user selected files) are being accessed, and how long they were accessed.

The files being monitored could be WORD documents, EXCEL
files or anything else !!

At the moment, I am using Delphi v1.0.
Watch Question

This is an advanced question.  
You have to use Windows-Hook in order to monitor the message
transformation between programms.

You should check for API function SetWindowHook, and SetWindowHookEx for Detailed information.

Another good article -- "An Window API example" is


This is an advanced question.
You have to use Windows-Hook in order to monitor the
message  transformation between programms.

>You should check for API function SetWindowHook,
>and SetWindowHookEx for Detailed information.

Thanks.  I checked these in Win API help, but was unsure
about whether to use a TASK or SYSTEM Hook, and what type of
Hook I needed - there are many.

BTW, it is SetWindowsHook SetWindowsHookEx (you were missing
an S) - no matter.

>Another good article -- "An Window API example" is

Borland must have moved the article - the link doesn't seem
to exist now.

Can you provide more information / example on using
SetWindowsHookEx ?

This can not be done using hooks.

AFAIK, You'll need to use DPMI and some undocumented DOS interrupts. Never tried though.




OK, so are we back where we started ?

Can anybody help me solve this problem ?

CleanSweep does something similar, so it must be possible.

All help and suggestions, much appreciated.


I could give it a try.

But, I'm not sure I understand what you wan't?

1) You have a filename, and need to know if you can access the file

2) You have nothing and need a list of all open files

1 is simple, 2 is a lot of work.

I'll need to know a few things if you wan't option 2.

On which OS'es do you intend to run this app? 3.1/95/NT
Will it stay 16-bit?




I need to know if a user selected file is currently
open or being used and monitor how long it was open / used.

Without giving away too much about the great new application I am writing, I want to be able to monitor user selected files
and log how long these (user slected) files were being used / accessed / opened.

I don't need an answer accurate to the nearest milli-second - the nearest few seconds would be OK.

The way I envisage it working is this :
- my program calls or hooks something in windows and checks all program acceses or requests to open / read files.
- if it is a file I am monitoring, start a stop watch for that file.
- when the file is closed by the application or it is no longer being read / accessed, then stop the stop watch and write an entry to a log file tp record the date, times and length of time that the file was accessed.

That is exactly what I need to do in a nutshell.

I hope you can help.


The method I'm thinking of would (if it works) make you able to at any given time obtain a list of all open files. According to docs it should work, but as it'll rely on "unofficial" dos calls there's no guarantee they are supported under windows.

It would *not* work on Windows NT, and it *might* work on 95.

You would ofcourse have to obtain this list e.g. every few seconds, and then compare it with the previous list to find out what's changed.

I'll give this a try during the next few days... I'll have to deliver my current project first, though.




Thanks for your help Erik !!

What do you say on this luoxiao ??

If possible, I would like to stay in Windows 3.x land and be compatible with WIn 95 and Win NT.

However, this might not be possible.

Does anybody know how CleanSweep monitors what files are being accessed ??

I thought that this would be the key to doing this under Windows.

Ah, well .....

Seeing this problem is so difficult, I have tried to up the points to 1000 !!

All help much appreciated !!



In the original Email I got about this question, it said that if I wanted more help from luoxiao, that I should rate the answer as 'F'.

I didn't like to do this because I didn't want to offend luoxiao - 'F' is far too harsh.

But, I do know if luoxiao is still helping on this question or whether Eric has taken over now.

So, I have added the suggested 'F' rating to see what is happening.


If you wan't to stay compatible with all windows versions, there is a much simpler approach... I can write you a simple function to which you pass a path and filename, and then the return value indicates whether it is opened or not.

This would mean that you have to go through the list of files at regular intervals, though.

Such a function ain't worth more than 100pts. If you wan't this, then just reduce points and let me know. If you wan't the "Get list of open files" function, which I've just verified doesn't work with NT, you'll have to give me a few days...

>Does anybody know how CleanSweep monitors what files are being accessed ??
>I thought that this would be the key to doing this under Windows.

I suspect they use a driver/VxD.... And then we're not in Delphi anymore...



I don't think it is possible to reduce points...if it is, I'd like to know how...I've tred before.

It ain't? I haven't tried... What happens if you delete a question? Do you lose points?

Anyway, I'll try writing both approaches in the next few days.


You can't get rid of your questions once they are asked either.  Supposedly there is code being tested right now that will remove unanswered questions after a period of time.

This is totally of topic...sorry.


>If you wan't to stay compatible with all windows versions, there >is a much simpler approach... I can write
>                       you a simple function to which you pass a >path and filename, and then the return value indicates
>                       whether it is opened or not.
>                       This would mean that you have to go
through the list of files at regular intervals, though.

This sounds excellent !!

This will certainly do for what I want right now.

I definetely wantm to stay compatible with all versions of Windows.

Can you please forward source code and anything else (doco, help, etc) that can help me understand how you did it.

And, ofcourse your name / Email so I can give you full credit
for your work in my program's readme !!  ;)

I tried to reduced points to 100 as requested - but I got a
"Sorry you cannot reduce points" error message.

Thanks very much for your help everyone !!


They don't allow you to reduce points or remove questions.  It would lead to major abuse by some folks.  They could post a 300 pt question, you could give an awesome answer, they could then reduce to 10 pts, then grade you.  Same goes for removing a question, except now you'd get no points for your answer.

function GetFileUsage (AFile : STRING) : INTEGER;
  pcFileName      : ARRAY [0..255] OF CHAR;
  hFile           : WORD;
  OpenFileStruct  : TOFStruct;
  PrevErrorMode   : WORD;

  { Tell Windows not to display any error dialogs, but rather
    return the errors to the app }
  PrevErrorMode := SetErrorMode (SEM_FAILCRITICALERRORS);

  { Assume that file exists and are not in use }

  { Create a PChar of the filename, and try to open exclusively}
  StrPCopy(pcFileName, AFile);
  hFile := OpenFile (pcFileName, OpenFileStruct, OF_READWRITE or OF_SHARE_EXCLUSIVE);

  { If we got an invalid handle in return, check the error codes}
  if hFile = $FFFF then begin
    case OpenFileStruct.nErrCode of
      $2,   { File not found  }
      $3,   { Path not found  }
      $15,  { Drive not ready }
      $1A,  { Not MS-DOS disk }
      $1B:  { Sector not found }
        Result := FILEUSAGE_NOTFOUND;

      $20,  {Sharing violation}
      $21:  {Lock violation}
        Result := FILEUSAGE_INUSE;
        { Here, one could try to open using OF_SHARE_DENY_WRITE,
        OF_SHARE_DENY_READ and OF_SHARE_DENY_NONE and detect how
        the file is locked }

      { Unrecognized error.
        These should preferably be written to some log file,
        along with the file name and nErrCode, to allow for
        later addition of a proper return value for the
        given nErrCode }
      Result := FILEUSAGE_ERROR;

  { If the handle is not invalid, we better close the file }
  if (hFile <> $FFFF) then _lclose(hFile);

  { Restore the error mode }
  SetErrorMode (PrevErrorMode);


I still don't think this is worth 255 points, therefore I suggest  that you offer 1 point on your next question, and I'll answer it if I can. OK?



Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts


Thanks loads Eric !!

I am off to give this a try and I will report back tomorrow !

Thanks for all your time !!



Sorry for the delay in reporting back.

The above code works fine - for applications that lock files while you are working on them - such as WOrd, Excel, Powerpoint, WOrdPerfect, Lotus 1-2-3, etc.

However, it doesn't work for programs that do not lock their files - such as Notepad, Wordpad, Paint Shop, Delphi, etc.

I think something more complex will be required for these other apps.

Any ideas ?


>However, it doesn't work for programs that do not lock their
>files - such as Notepad, Wordpad, Paint Shop, Delphi, etc.

That's because they open the file, read its contents and close it. When you save, they reopen, writes back and closes again.

Consider this: If you write a small program that opens a text-file, reads it into a memo and then closes the file, there is no way for anything besides your program to know whether you are still using the contents of the file, or if you have discarded all changes and cleared the memo...

In short, what you seem to want is one of the very few things I'd dare say cannot be done.



Actually, Quarterdeck's Cleansweep can register these kinds
of accesses.  But they certainly didn't do it in Delphi.
I'd gather they used a VxD, as per Sperling's previous comment.
I'm guessing they have inserted hooks into the file system.

By using a driver/VxD trapping all access to the file system, it is possible to trap every single file open, close, read, write, delete and so on.

But, if you open a file in e.g. notepad, and then closes it, only the "open file" and "read file" ever gets to the file system. Hard for any program to know that the user actually has closed the file, and that it logically ain't in use anymore.



Cleansweep doesn't need to register file closes.  It only needs
 to register file opens, as it simply catalogues a list of files
and when they were last used...that way you can remove files that haven't been used for a long period of time.

Cleansweep also monitors entire installs...it records where
every file was written, it records every change to any .INI
file, it records all changes to the registry.

It's a pretty good product.  I'm amazed it does all that it is
does.  It even registers the number of files that have been
accessed sice you installed the program and per session.
I've tested it a number of ways...even with the notepad thing
above...it catches it...as of now I've:
    1 252 385 files used since Sept. 17 1996
        6 503 files used since Apr.  23 1997 11:45 AM

Aha... Then I follow. (I've never seen CleanSweep) That is ofcourse possible, and in fact not very technical difficult to accomplish using a few drivers.

What I wouldn't believe, and still doesn't, was that it is possible for anything to know that I've just cleared the memo and thus logically discarded the file (from my example in some other comment).

If one added tracking of process shutdowns to CleanSweep, it would be possible to keep an approximate if not exact list of files that are physically and logically in use.

This seems like something that would be fun to write... But then, most of it already exists, so why bother...

Anyway, as far as I can see there's no way this can be done without a driver intercepting file system calls. Might ofcourse be some obscure API to get notifications of file access, but I doubt it.

And, I ain't going to write such a driver for anything but cash ;)


Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.